I have a wxPython project that is showing some weird symptoms in Windows 7 (everything works fine on Mac OS X, Windows 7 is the only win version we're testing against for this version). The app has a subclass of wx.TaskBarIcon with a right-click menu that should create windows that should always stay on top. Each window is a subclass of either wx.Frame or wx.Dialog created by wxFormBuilder.
Sometimes, and I cannot find the steps to reproduce it, the windows don't show up and cannot be called to the front. The app's icon will appear in the taskbar but the window will not appear. Clicking the icon does nothing and even by closing all other windows the window is not shown.
Snippet of how I'm currently showing the window:
#Initialization code, calling super's __init__ etc.
self.Center()
self.Show()
self.SetWindowStyle( self.GetWindowStyle() | wx.STAY_ON_TOP )
Since I can't reproduce the problem debugging it is hard. I've tried calling self.Raise and self.SetFocus after self.Show but the problem comes up again now and then. Has anyone experienced similar problems with wxPython or know any possible fixes for this?
As I recall, you normally can't change Frame styles after initialization reliably. You should just put the STAY_ON_TOP style flag in the Frame's init instead. For dialogs, use ShowModal(). Now that I think about it, you can also use the frame's MakeModal() method and that would probably work too.
Related
I am developing a cross platform app in Python using wxPython. The app is fully developed, and the graphics toolkit is set in stone, at least for the time being.
On Windows, everything looks great. On Linux, everything looks pretty good. On Mac, I am having trouble with a combobox/choice being hidden in the toolbar, even though it shows up fine on Windows.
Here is a snapshot of my app on Linux, noting the entire "CoeffConv ..." section is part of the perfectly displayed combobox:
And here is a snapshot of the same exact codebase on Mac:
I've tried with wx.ComboBox and wx.Choice with the same effect. I've made sure to call Realize() after I've added my toolbar items. I've made sure AddControl is called to actually add the object to the toolbar. It's definitely trying to render because the spacing is exactly what I would expect, given the contents of the choice field.
In fact, if I don't call AddControl, but I create the choice field with the toolbar as the parent, the box gets rendered but things aren't arranged properly due to the missing AddControl call:
As another check, I created a super simple toolbar with choice demo, and it works just fine:
So, here's the summary of things I know:
On Windows, the choice field works perfect, indicating the code isn't necessarily wrong.
On Linux, the choice field works perfect, supporting the idea that the code is actually OK.
On Mac, the choice field is present it seems, but somehow invisible, implying this is a problem with the Mac, or the Python distribution on Mac, or the combobox control in the wxPython distribution on Mac.
On Mac, I can get the choice to render (improperly but still) without an AddControl call, indicating the combobox can render properly, but something is goofy about the placement when added to the toolbar
However, On Mac, I can get a toolbar/choice to render totally fine in a dummy example, indicating it's something about my implementation...but I can't figure out what would cause it as I'm trying to make the exact same calls to the wx objects as in the dummy example.
I can't get the dummy example to reproduce the problem, but I'll keep trying. I'm happy to report out some object properties if they would be helpful in diagnosing. If someone has a clue for what could cause it to not show up, I'd really appreciate it!
While I couldn't find the root as to why it didn't work on Mac, I did find an issue that could help others.
First a little more background. In the app, we have multiple toolbars. Because of that, we are creating toolbars using plain wx.ToolBar objects and adding them to the app frame using sizers. This is in contrast to the more standard method of using self.CreateToolBar() which only allows a frame to have a single toolbar.
When I make a single change to the code to use the more natural CreateToolBar interface, the combobox immediately shows up. When I do that, the second toolbar is messed up, but at least the initial toolbar works perfectly. I'll be investigating how to get multiple toolbars on Mac, but it's a step in the right direction.
It's been a while, but there's another solution to this for wxPython 4 if you can't use CreateToolBar():
The widgets do get added to the bar and reserve the correct amount of space, but they fail to draw properly. You can resolve this by calling control.Hide() followed by control.Show() on each widget control, which then makes them draw properly.
I created a PyGTK application which needs to be always on top. The transparent window redirects mouse clicks to the window below and therefore gets out of focus once you click into an underlaying window. This is the intended behaviour. In fact it should just show a little image that's always above everything.
This works well unless you use something like the libreoffice fullscreen presentation. The presentation window is marked as always on top as well and hence my window goes into the background. Even if I take it to front using Alt+Tab and then click onto the underlaying libreoffice slide (which is neccessary) my window goes into the background again.
This is a really specific question and the solution should work on both Linux and Windows. I have no idea what I should do. I just found many questions on how to have a windows always on top but none of them covering my problem.
Long story short: How can I put my window always on top of every window that is always on top as well?
Simple Answer: You can use 'Always on Top' in windows with by using AutoHotKey scripts.
Follow these steps:
Install AutoHotKey
Create a new AHK scripts following the images
Add this code ^SPACE:: Winset, Alwaysontop, , A
Next, double-click your script to run it. You’ll know it’s running
because a green “H” logo appears in your system tray to let you know
it’s running as a background process.
Now press Ctrl+Space to set any currently active window to be always
on top. Press Ctrl+Space again set the window to no longer be always
on top.
GNOME Developer Center website shows About Dialog without an icon. On Ubuntu 16.04 LTS however, it seems that GTK now requires for icon to be present, as without explicitly declaring icon name, that very same example form the website it shows error icon.
Thus the question: how do I get around this issue ? I want the About dialog for my program only have simple text and no icon/logo.
I know I'm a little late to the party but I just stumbled upon your question because I was too searching for an answer to this. What worked for me was this:
about = Gtk.AboutDialog() # Create your about dialog object
about.set_logo_icon_name(None)
By passing None to set_logo_icon_name the default window icon set with the gtk.window_set_default_icon_list() function will be used. If you haven't specifically specified a default window icon then no icon/logo will be rendered.
i am using python/tkinter to write a IM software on XP. now i've got all the main functions done except i don't know how to highlight or change colour my IM item on taskbar on windows xp when window is minimized to the taskbar when a new message is received. i've search for this but just got c# solution. i need help on python. thanks!
I needed to do this for a tkinter python slack client I am writing and found http://wiki.tcl.tk/1049 . After a bit of guessing, I found that
Tk().deiconify()
Tk().focus_force()
(i.e. on the root window) does the trick. Windows doesn't actually change the focus and show the window since applications are not allowed to do that (Windows after XP) but it flashes the taskbar instead. It will keep flashing until clicked on but that seems to be the behaviour of Skype/Slack etc. Certainly close enough for many uses.
Obviously this is an old question but I couldn't find a concise, python only, answer and still needed one!
I'm not sure if there is a good way of doing this with Tk. Maybe somebody more knowledgeable will be able to point you in a better direction. Since Python is so dependent on OO, you may have a difficult time writing bindings to the Windows window manager.
If you don't find anything else, I did stumble on http://wiki.tcl.tk/4089, which manages Windows icons on the taskbar. Perhaps you could utilize this to simulate the taskbar flash that you want?
I am writing a wxPython application that remains open after closing all of its windows - so you can still drag & drop new files onto the OSX dock icon (I do this with myApp.SetExitOnFrameDelete(False)).
Unfortunately if I close all the windows, the OSX menubar will only contain a "Help" menu. I would like to add at least a File/Open menu item, or just keep the menubar of the main window. Is this somehow possible in wxPython?
In fact, I would be happy with a non-wxPython hack as well (for example, setting the menu in pyobjc, but running the rest of the GUI in wxPython). wxPython development in OSX is such a hack anyway ;)
UPDATE: I managed to solve this problem using the tip from Lyndsey Ferguson. Here's what I have done:
On startup I create a window which I show and hide immediately. I set its position to (-10000,-10000) so that it does not flicker on the screen (aargh, what a dirty hack!)
I create an empty EVT_CLOSE event handler in that window so that it cannot be closed.
It seems that destroying a window resets the OSX menu, but hiding does not... So when the last window is closed, I need to show and hide this window again (hiding is necessary so that the user cannot switch to this window using the Window menu or Cmd-`)
Yeah, this is really ugly... I will be very grateful if someone comes up with a prettier solution.
UPDATE 2: Actually it can be solved in a much easier way: if we do not close the last window, only hide it. And ensure that it does not respond to menu events anymore.
Nowadays you can use wx.MenuBar.MacSetCommonMenuBar() to set the menu bar (which you have to create) that should be used when no windows are open.
If you just want a default macOS menu bar to be used (with the application and Window menus already there), this appears to be the minimal code:
menubar = wx.MenuBar()
wx.MenuBar.MacSetCommonMenuBar(menubar)
This will let your app respond to Command+Q out-of-the-box, too.
The wx.MenuItem IDs wx.ID_ABOUT and wx.ID_EXIT are special as menu items with those IDs are moved to the macOS Application menu. The docs actually refer to the application menu as the "Apple" menu (e.g. the menu described in the wx.MenuBar.OSXGetAppleMenu() function's docs is the application menu), possibly for historical reasons.
Can you create a hidden window that is offscreen somewhere? It is a hack, but I remember having to do a lot of hacks to make my wxPython-based application work correctly on Mac OS X.
Note:You'll have to disable the close button and set up that hidden window so that it doesn't show up in the Window menu.
Aside:Have you considered factoring out your GUI portion of your Python application and using PyObjC on Mac OS X? You'll get more native behaviours...