wxPython from Linux to Windows - linux

I have a wxPython application developed on Linux that I wish to deploy on Windows machines. While most of the things work well on porting there are small (but catastrophic) problems, none of which seem related. Rather than list them all, I'll start with one.
I have an array of images that I read in and place in a GridBagSizer in a Class. Unfortunately, the 'Bind' statement doesn't seem to take effect, and when I double-click on an image 'onSuitDClick' is not called.
suitSizer=SuitDisplay(self, suit
def onSuitDClick(self, event):
print 'sc'
class SuitDisplay(wx.Panel):
def __init__(self, frame, suit):
wx.Panel.__init__(self, frame, id=wx.ID_ANY)
suitSizer=wx.GridBagSizer(1, 13)
suitList=[]
for ii in range(0, len(g.CARDS)):
if g.CARDS[ii]+g.SUITS[suit] in frame.availableCards:
card=g.CARDS[ii]+g.SUITS[suit]
suitList.append(card)
for ii in range(0, len(suitList)):
card= suitList[ii]
image = wx.Bitmap(frame.imageFolder+card+'.png',wx.BITMAP_TYPE_PNG).ConvertToImage()
img = wx.StaticBitmap(self, -1, image.ConvertToBitmap(), name=card)
img.Bind(wx.EVT_LEFT_DCLICK, frame.onSuitDClick)
suitSizer.Add(img, pos=(0,cardPos), flag=wx.LEFT, border=border)
self.SetSizer(suitSizer)
Needless to say, this works perfectly in Linux.
Can anyone suggest where I might look for a solution?

Related

Issue with rendering screens & background in python arcade

I am having difficulty getting a simple python Arcade app to work on my Win10 machine. I think the issue is with the "start_render" function not taking effect. I have the following issues:
the screen does not "redraw", i.e., all existing sprites remain on the screen and are never removed. if I run some of the builtin code samples I get the character redrawn on the screen 100s of times as it moves
the background color is never drawn on; it always remains black
Using the "finish_render()" method in the on_draw() method does not work either; it creates a constant flickering and not a stable view
The sipmle code I'm running is below.
import arcade
class TestUI(arcade.Window):
def __init__(self, width, height, title):
super().__init__( width, height, title)
def setup(self):
arcade.set_background_color(arcade.csscolor.BLUE)
def on_draw(self):
arcade.start_render()
arcade.draw_circle_filled(100,100,50,arcade.csscolor.TEAL)
def main():
app = TestUI(1200,800,"Test game")
app.setup()
arcade.run()
if __name__ == '__main__':
main()
This gives me a Teal circle on a full black background. If I run one of the code examples
python -m arcade.examples.sprite_moving_platforms
I get the constant redrawing (see screenshot)
I am running the following versions:
Python 3.7.4
Arcade 2.5.7
On a Windows 10 machine
Any pointers on what could be going wrong?
Thanks!

tkinter image appearing partially white instead of correct colour

Recently i have been trying to get gifs to work with tkinter and after some research i figured out how i was going to do it and wrote a class to make playing them easier
class GifWrapper():
def __init__(self, parent, file=None):
self.file=file
self.parent=parent
if file:
self.info=parse(file=file)
else:
raise GifError("expected file to be passed")
print(str(self.info.frames)+" "+str(len(self.info.delays)))
self.frames=[]
for i in range(0, self.info.frames):
self.frames.append(PhotoImage(file=self.file, format="gif -index {}".format(i)))
print("added frame {}".format(i))
async def play(self):
curFrame=0
for i in self.info.delays:
await asyncio.sleep(i/100)
self.parent["image"]=self.frames[curFrame]
curFrame+=1
However when i tested this out i noticed that my gif was pretty strange as seen here, the first frame seems to be only slightly affected, the second frame seems perfectly ok and the rest are pretty badly affected by the issue, i remember reading somewhere that pixels with an alpha of 0 were treated as transparent in PhotoImage files so i assume that this might be the problem however i think it's weird that the first and second images are affected differently, is there a way to change this?

Pyglet hello world example doesn't show label until a key is pressed

import pyglet
window = pyglet.window.Window()
label = pyglet.text.Label("Hello World!",
font_name="Times New Roman",
color=(255,255,255,255),
font_size=36,
x=window.width//2, y=window.height//2,
anchor_x="center", anchor_y="center")
#window.event
def on_draw():
window.clear()
label.draw()
pyglet.app.run()
This code is taken from the pyglet tutorial at https://pyglet.readthedocs.io/en/pyglet-1.2-maintenance/programming_guide/quickstart.html but when run it doesn't draw the label until any key is pressed. I added the color as I thought the text may have defaulted to black.
Am I missing something really obvious as to why this behaviour is happening?
OK, having had my memory jogged by the comments, I installed the MS Fonts and it now works in python 2.x but I still need to press a key to see the text in python 3. Maybe the font thing is a red-herring and there is some incompatibility with python 3.
As mentioned in the comments.
Most examples found on the internet (even most guides) assume a Windows platform.
If there's a font= declaration with a Windows font but you're running Linux, make sure you got the proper fonts installed or revert to a font you've got installed.
$ fc-list
Also not declaring a font will work too:
label = pyglet.text.Label("Hello World!",
color=(255,255,255,255),
font_size=36,
x=window.width//2, y=window.height//2,
anchor_x="center", anchor_y="center")
Because Pyglet will default to sans-serif:
If you do not particularly care which font is used, and just need to display some readable text, you can specify None as the family name, which will load a default sans-serif font (Helvetica on Mac OS X, Arial on Windows XP)
Your issue is probably that you don't manually update the screen after you drew something. Normally when you press a key, it forces a window.flip(), which basically means update the screen content.
window.clear() also triggers this behavior, but x.draw() does not. Why? Well the thing that takes time in computer graphics is not really the calculations, it's the updating them to the screen that takes time.. There for .draw() doesn't update the screen, it just puts the stuff in the graphical buffer ("page"), you decide when to flip the page and show the new buffer on the screen.
Try this out:
#window.event
def on_draw():
window.clear()
label.draw()
window.flip()
This might be a overkill solution, but it will probably solve the problem.
This overrides the default loop of pyglet and the default draw behavior, it's also one of the classes i use the most in my pyglet projects since it gives me the option to create my own framework.
import pyglet
class Window(pyglet.window.Window):
def __init__(self):
super(Window, self).__init__(vsync = False)
self.sprites = {}
self.sprites['testlabel'] = label = pyglet.text.Label("Hello World!",
color=(255,255,255,255),
font_size=36,
x=self.width//2, y=self.height//2, #self here, being pyglet.window.Window that we've inherited and instanciated with super().
anchor_x="center", anchor_y="center")
self.alive = 1
def on_draw(self):
self.render()
def render(self):
self.clear()
for sprite_name, sprite_obj in self.sprites.items():
sprite_obj.draw()
self.flip()
def on_close(self):
self.alive = 0
def run(self):
while self.alive:
self.render()
# This is very important, this queries (and empties)
# the pyglet event queue, if this queue isn't cleared
# pyglet will hang because it can't input more events,
# and a full buffer is a bad buffer, so we **NEED** this!
event = self.dispatch_events()
win = Window()
win.run()
It's extremely basic, but you can add more sprites, objects and render them in def render(self):.

How do I set the minimum size of a Gtk ButtonBox child?

I'm trying to set the minimum size of the buttons in this GtkButtonBox. Currently they seem to be fixed - approx 85 pixels I think.
Is this possible?
If not, is there another way in Gtk to get two small sized buttons to snuggle together like in the above picture rather than having them appear to be two separate buttons? For example GtkStackSwitcher may be something I could use but there doesn't appear to be a way to respond to click events for a button.
I've used this test program to create the above (Ubuntu 14.04, Gtk+3.10 and Python3):
from gi.repository import Gtk
import sys
class MyWindow(Gtk.ApplicationWindow):
def __init__(self, app):
Gtk.Window.__init__(self, title="example", application=app)
self.set_default_size(350, 200)
self.set_border_width(10)
hbox = Gtk.ButtonBox.new(Gtk.Orientation.HORIZONTAL)
hbox.set_layout(Gtk.ButtonBoxStyle.EXPAND)
button = Gtk.Button(label="a")
hbox.add(button)
button2 = Gtk.Button(label="b")
hbox.add(button2)
self.add(hbox)
class MyApplication(Gtk.Application):
def __init__(self):
Gtk.Application.__init__(self)
def do_activate(self):
win = MyWindow(self)
win.show_all()
def do_startup(self):
Gtk.Application.do_startup(self)
app = MyApplication()
exit_status = app.run(sys.argv)
sys.exit(exit_status)
With regards to a question about the desktop environment I'm using.
I've tried Mate, Unity and Gnome-Shell. All work the same way. I've removed the title and those controls. Still the same thing happens. To me this looks more like a GTK issue.
I believe that GtkButtonBox imposes some layout constraints on its buttons that you may not want here. Try using buttons in just a regular GtkGrid, but give them the GTK_STYLE_CLASS_LINKED CSS class.
For each button, do:
button.get_style_context().add_class(Gtk.STYLE_CLASS_LINKED)

Show QMainwindow in the middle of the screen

I want show my project main window in the middle of the screen . when i call "self.show()" then the window show in the middle of the screen .
I know you have already solved it, but I make this answer for those who have the same question. I post it mainly because you asked for pyQt and the other answer is for Qt (C++).
I found a workaround here: https://bashelton.com/2009/06/pyqt-center-on-screen/
Is so simple and works perfectly, I transmit it..
class ExampleWindow (QtGui.QMainWindow):
def __init__ (self, parent=None):
'''constructor'''
QtGui.QMainWindow.__init__(self, parent)
self.setGeometry(0, 0, 650, 550)
self.setWindowTitle("My Example Application")
self.centerOnScreen()
def centerOnScreen (self):
'''centerOnScreen()
Centers the window on the screen.'''
resolution = QtGui.QDesktopWidget().screenGeometry()
self.move((resolution.width() / 2) - (self.frameSize().width() / 2),
(resolution.height() / 2) - (self.frameSize().height() / 2))
Good luck!
First I would recommend against trying to force a window position on your users and let the system's window manager decide where it should go. If you really insist on positioning it yourself (perhaps you are programming for a kiosk), you can find some information here in a previous question on stackoverflow.
A slightly more elegant calculation for doing this is discussed here.
When doing this calculation, it is important that it is done at the correct time, after Qt has resized everything and just before it is shown on screen. One method that might help is to create a one-shot timer and do the screen positioning in the slot for the timer.
This worked for me in Pyqt5:
from PyQt5.QtWidgets import *
qtRectangle = self.frameGeometry()
centerPoint = QDesktopWidget().availableGeometry().center()
qtRectangle.moveCenter(centerPoint)
self.move(qtRectangle.topLeft())

Resources