Hi I have a nokia 5800 phone on which I was doing some pys60 ui programming. I used the below code to create the arrow. In short the draw() will draw the arrow onto the canvas surface. The canvas has redraw_callback and resize_callback hooked up to call draw() eventually. But on tilting I get some random text (garbage) output on the screen.
import appuifw
from appuifw import *
import e32
from graphics import *
def up(dummy):
appuifw.note(u'Button 1 Clicked', 'note')
def down(dummy):
appuifw.note(u'Button 2 Clicked', 'note')
appuifw.app.screen = 'normal'
def on_resize(dummy):
draw()
def on_redraw(dummy):
draw()
def on_exit():
global lock
lock.signal()
def draw():
global canvas
canvas.clear()
canvas.polygon((20,20,20,60,40,40,20,20), fill=(255,0,0), width=10)
canvas = appuifw.Canvas(resize_callback=on_resize, redraw_callback=on_redraw)
lock = e32.Ao_lock()
appuifw.exit_key_handler = on_exit
draw()
lock.wait()
Here is how it looks when I've held the phone straight up.
Here is how it looks when I've tilted it.
Note that the space that has the text (in landspace) is the size of the width minus the width it was when the orientation was portrait. Are you forgetting to resize the canvas to the landscape new dimentions?
It seems the text is the console output, check what is not being defined and whatever else is being output there.
appuifw.app.orientation = 'portrait'
or even:
appuifw.app.orientation = 'landscape'
Related
I created a 10 000 x 10 000 pixel canvas, placed it inside a scroll pane with dimensions 300 x 300. This was implemented fine. The whole grid was drawn and I could scroll through it.
I'm tasked to instead create the same functionality, except with a 300 x 300 canvas instead. As speed is important in this program, I'm told this would work much faster.
My problem is that when I do this, I lose access to the scroll bars on the bottom and right of the scroll pane. How do I regain access to those scroll bars, to physically scroll?
The canvas is updating at 60 steps per second. What's being drawn is a square grid from the information in a 2D array.
Since the the viewport handling will be done by the drawing logic, it's rather easy to create a "ScrollPane" yourself using a GridPane:
public static ScrollBar createScrollBar(Orientation orientation, double fullSize, double canvasSize) {
ScrollBar sb = new ScrollBar();
sb.setOrientation(orientation);
sb.setMax(fullSize - canvasSize);
sb.setVisibleAmount(canvasSize);
return sb;
}
Canvas canvas = new Canvas();
canvas.setHeight(300);
canvas.setWidth(300);
ScrollBar vScroll = createScrollBar(Orientation.VERTICAL, 10000, 300);
ScrollBar hScroll = createScrollBar(Orientation.HORIZONTAL, 10000, 300);
GridPane scrollPane = new GridPane();
scrollPane.addColumn(0, canvas, hScroll);
scrollPane.add(vScroll, 1, 0);
Is there a way to get a fade-in/-out animation on a canvas rectangle background in kivy? I tried it by using the Clock.schedule_interval() function. But several problems occured concerning concurrency and data raise.
One of my tries looks as follows:
def calendarClicked(self, *args):
self.alpha = 1.0
self.alphaDelta = 0.01
self.root.canvas.add(Color(1,0,0,self.alpha))
self.root.canvas.add(Rectangle(size=self.root.size))
def fadeIn(self, dt):
self.alpha -= self.alphaDelta
self.root.canvas.add(Color(1,0,0,self.alpha))
self.root.canvas.add(Rectangle(size=self.root.size))
return self.alpha >= 0.5
Clock.schedule_interval(partial(fadeIn, self), 0.1)
Another idea was to use the kivy.animation. But I coudn't find a way to edit the color instead of the position of an object/widget.
Thanks in advance!
You can use an Animation on canvas instructions just like you would a widget. The problem is that you're not modifying the canvas instructions at all, you just keep adding more and more canvas instructions. You need to add the instructions one time only, then update the values via Animation.
def calendarClicked(self, *args):
if not hasattr(self, 'color'):
with self.root.canvas:
self.color = Color(1, 0, 0, 0)
self.rect = Rectangle(size=self.root.size)
self.color.a = 0
anim = Animation(a=1.0)
anim.start(self.color)
My question concerns the sdl2.ext.Renderer mainly, and has to do with a problem I've encountered when trying to render sprites on a sdl2.ext.Window surface.
So right now, for coloring my background on an SDL2 Window, I make the following call:
White = sdl2.ext.Color(255,255,255)
class Background(sdl2.ext.SoftwareSpriteRenderSystem):
def __init__(self,window):
super(Background,self).__init__(window)
sdl2.ext.fill(self.surface,White)
This colors the surface of the Window with a white background. However, I also want to display text on the screen. This is done by creating a TextureSprite using the from_text method of the sdl2.ext.SpriteFactory class as follows:
Renderer = sdl2.ext.Renderer(W) # Creating Renderer
ManagerFont = sdl2.ext.FontManager(font_path = "OpenSans.ttf", size = 14) # Creating Font Manager
Factory = sdl2.ext.SpriteFactory(renderer=Renderer) # Creating Sprite Factory
Text = Factory.from_text("Unisung Softworks",fontmanager=ManagerFont) # Creating TextureSprite from Text
Renderer.copy(Text, dstrect= (0,0,Text.size[0],Text.size[1])) # Resizing the Texture to fit the text dimensions when rendered
The problem occurs when the event loop is run.
running = True
while running:
events = sdl2.ext.get_events()
for event in events:
if event.type == sdl2.SDL_QUIT:
running = False
break
if event.type == sdl2.SDL_MOUSEBUTTONDOWN:
pass
Renderer.copy(Text, dstrect= (0,0,Text.size[0],Text.size[1]))
Renderer.present() # Problem 1
W.refresh() # Problem 2
return 0
Full Example Paste
When both Renderer.present() and W.refresh() are called, I get a flickering effect from the screen. This seems to be because the Renderer overwrites the White colored Window surface, which then gets colored over again by the Window.refresh() call. This then repeats, resulting in a flickering mess.
I would like to know what I can do to solve this problem? Should I even be using both Window.refresh() and the Renderer at the same time? Is there a way to let one render the other? (Renderer renders background for example). If anyone can help me out, that would be great.
The problem is that you are using Window.refresh() along with a SDL_Renderer and a SoftwareSpriteSystem with SDL_Texture objects.
As outlined in the PySDL2 docs, this is likely to break (since software surface buffers get mixed with hardware-based textures) and you should avoid it. If you want to color the window background, you should use Renderer.clear(White) instead of your Background class and call it before copying the text via Renderer.copy():
Renderer.clear(White)
Renderer.copy(Text, dstrect= (0,0,Text.size[0],Text.size[1]))
Renderer.present()
Do not forget to change the color for your FontManager. By default it uses a white text color, so you should change it to e.g. your Red color:
ManagerFont = sdl2.ext.FontManager(font_path = "OpenSans.ttf", size = 14, color=Red)
I am using tkinter when and trying to set up a window with a background image. In some of the processes I have a frame that fills up with checkboxes so I created a scrollbar so the user can see all the options. The problem is the scroll bar also moves the background image of the canvas. Is there a way I can fix the image to not move or somehow move the frame by itself.
code is
def canvasScroll():
canvas = gui.createCanvas()
fFrame = gui.createNewFrame()
scrollbar = Scrollbar(root, orient="vertical", command=canvas.yview)
canvas.configure(yscrollcommand = scrollbar.set)
scrollbar.pack(side="right", fill="y")
canvas.pack(side="left", fill="both", expand= True)
canvas.create_window((150,50),window = fFrame, anchor='nw', tags = "frame")
gOb.change_canvas(canvas)
fFrame.bind("<Configure>", gui.scroll)
gOb.change_scrollbar(scrollbar)
gOb.change_frame(fFrame)
def createCanvas():
canvas = Canvas(root,height = _h, width = _w,highlightthickness = 0)
canvas.pack(side='top',fill='both',expand='yes')
canvas.create_image(-200,-200,image=bground,anchor='nw')
return canvas
def createNewFrame():
frame = Frame(root,height = _h, width = _w,background='white')
frame.pack()
return frame
Just to clear things up, these guys are all part of a class name gui and gOb is an object that hold several gui objects.
Here's one idea - it's kind of kludgy, but it would work. Every time the scrollbar scrolls, shift the background image's position so it appears to stay in the same place:
Tag your image so you can access it later:
canvas.create_image(-200,-200,image=bground,anchor='nw',tags="background")
# ^^^^^^^^^^^^^^^^^
Make your scrollbar call a function that you define:
scrollbar = Scrollbar(root, orient="vertical", command=scrollCallback)
Define your scroll callback:
def scrollCallback(*args):
canvas.yview(*args)
# Arrange for your background image to move so it appears to stay in the same position as the canvas scrolls.
I am currently working on a school project and missed a class where the instructor explained how to do this without a massive amount of code.
Here is the assignment:
Create an XNA application shows 50 animated sprites accelerating downward. When a sprite hits the bottom of the window, make it bounce. Spawn each sprite in a random location such that the sprite is always completely in the window. Limit the Y component of the random location to be between 0 and 300. Lastly, make it so the sprites reset to their original location upon a press of the space bar.
This is a link to an example image, rep isn't high enough for inserting images
http://hypergrade.com/grader/file_download.php?id=132
I have a single sprite drawn and animated, I just need some guidance on randomly generating locations for the same Texture2D.
you should use Random class.
// Make one instance of random, the seed is the milliseconds, other way random always returns the same sequence of random numbers.
static readonly Random rnd = new Random(DateTime.Nom.Milliseconds);
List<Sprite> Sprites = new List<Sprite>(50);
public void Update()
{
//Add new sprites with a 90% or probability
if (Sprites.Count<50 && rnd.Next(100) > 90)
{
Sprite sprite = new Sprite();
// This X calculation makes the sprite not to get out of the screen at both sides
sprite.Pos.X = (float) ( (0.1f + 0.8f * rnd.NextDouble()) * GraphicsDevice.Viewport.Width);
sprite.Pos.Y = (float) ( rnd.NextDouble() * 300 );
Sprites.Add(Sprite);
}
}
Of course de Sprite class depends on you.. :)