Segmentation fault using Python gtk3 with pyOpenGL - python

I use Python in combination with the gtk3 and the GTKGLExt fork from https://github.com/tdz/gtkglext so I can use the gobject introspection feature to use Gtk3 from python.
I created a Gtk.DrawingArea to draw my OpenGL stuff. Everything works fine as long as I have just one instance of this widget.
However, I use a Gtk Notebook to have multiple instances of this widget present in different pages of the notebook (one widget per page).
Sometimes (meaning in a non deterministic way) the program crashes with a segmentation fault. I ran a stacktrace using gdb and located the problem to be the call to "gtk_widget_end_gl" which is placed at the end of my drawing, realize and configure handler methods (of course there is a gtk_widget_begin_gl at the beginning of each of those as well).
Here is the relevant excerpt from the stacktrace:
0 0xb1170b58 in _gdk_x11_gl_context_impl_get_current () at gdkglcontext-x11.c:514
1 0xb116c094 in gdk_gl_context_get_current () at gdkglcontext.c:244
2 0xb116c0b4 in gdk_gl_context_release_current () at gdkglcontext.c:215
3 0xb4d04592 in gtk_widget_end_gl (widget=0xa175608, do_swap=0) at gtkglwidget.c:549
and below is a minimal example of my realize method where the problem occurs where "widget" is an instance of Gtk.DrawingArea:
def on_realize(self, widget, *user_data):
if not GtkGLExt.widget_begin_gl(widget):
return False
gl.glClearColor(BACKGROUND_COLOR[0],
BACKGROUND_COLOR[1],
BACKGROUND_COLOR[2],
BACKGROUND_COLOR[3])
GtkGLExt.widget_end_gl(widget, False)
Since I am pretty much clueless why this problem occurs sometimes (around every 5th time a new widget is created) I wonder if anyone ever has experienced the same or can reproduce the problem or help me to find a solution.
I need to say that I don't manually create an OpenGL context here since in the provided examples this never seemed necessary and I figured the widget would do this on it's own. The stacktrace implies that there seems to be a problem getting the context. Whats startles me is the fact that this only happens sometimes. So if someone could even hint me how to tackle this problem I would be very glad as I am not an experienced C programmer.

Related

WxPython Choice Field Invisible just on Mac

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.

Can I embed a matplotlib plot in a Tcl/Tk application?

I'm wondering how difficult it will be to use invoke matplotlib from a Tcl interpreter and plot to a Tk canvas created on the Tcl side.
I'm wondering what the best way to do this is.
I'm guessing I'll have to create a python interpreter, pass the canvas handle from the Tcl side to python and make use of the C API in both languages. Or is there a more elegant way?
Getting this integration right won't be easy. However, here's what I'm thinking about:
Connecting Python and Tcl
You can run Python inferior to Tcl apparently. According to this wiki page, there's a package called tclpython which can do the basic integration work for you, and the page linked to appears live. The code appears to be here, though it might need some work to make it build. (I've never tried.)
Connecting matplotlib and Tk
You can make matplotlib draw on a Tkinter window, and as long as you can make that Tkinter window with the right options, it will show up. The key is that the underlying system window IDs can be found out from Tk with winfo id $nameOfTheWindow. If you create a frame with the -container option set to true (which turns off some things and turns on a few others; you'll need to set the size explicitly) then that particular frame will be suitable for use with TkAgg on the python/matplotlib side. The key will be to make a toplevel on that side that has the -use option set to the ID retrieved from winfo id. You probably need to make sure that the python side is running its rendering in a separate thread to the outer Tcl/Tk to make the event handling work right (unless you're keen on doing deep event loop hacking; the situation is that you're actually going to have Tcl/Tk inside Python inside Tcl/Tk, as Tkinter works by delegating to a subordinate Tcl/Tk, and getting all this glued together right will be “a bit tricky”).
If that doesn't work, get matplotlib to render as an image (GIF or PNG; the latter is preferred if you've got Tk 8.6) as you can just show that easily via a photo image. This is definitely going to be possible to do without thread games; it's just passing around pure data. Probably slower and not interactive, but that might not matter for what you're doing, and it is easier in the simple case.
You will probably need the second approach if you're on Windows or OSX, as Tk there doesn't actually use X11. (Unless you're using one of the more perverse configuration options, of course.)

Switching Windows with Python

I'll preface this by saying that I'm very inexperienced with python, and I'm hoping that means the solution to my problem will be simple.
My program will be performing simple actions in another window, so ideally I would like my script to make sure that this other window is maximized and active before it proceeds with the rest of the commands. This has proved to be much more difficult than I had expected.
I am fairly certain that I can achieve this with win32gui using find_window and setting it to the foreground. I thought I had found my solution when I came across this previous question:
Python Window Activation
Unfortunately I was unable to use the solution code or manipulate it to solve my problem for a few reasons:
-The way that user had defined find_window only allows you to choose by the classname of the window, which I don't know and haven't been able to find since it is just a game running in Java. I couldn't seem to change that line to work for the specific windowname (Which I do know) as it is not the "default argument".
-I don't want to enumerate the windows to find it as I'm not sure how that would work.
-using find_window_wildcard as it's written in that script has managed to bring the window to the foreground a few times, but only if the window was already open, and it only works intermittently.
-set_foreground() requires one input statement and no matter how I try to set it I am always given an error that I either have the wrong number of elements or an invalid handle on the window.
I know that I'm stupid; but a clear and concise solution to this problem or at least a good explanation of the find_window/getwindow syntax would be a godsend to myself and anyone else who's having this problem.
I would strongly suggest you take a look at the pages for Swapy and for pywinauto. They can help you do some awesome things when it comes to UI Automation.
The way that user had defined find_window only allows you to choose by the classname of the window
The way the user defined it is to pass the two parameters class_name and window_name through, untouched, to win32gui.FindWindow (which in turn just calls the Win32 API function FindWindow). So, just do this:
windowmgr.find_window(None, 'My Window Name')
But even if that weren't true, you don't need to use his find_window function; it should be pretty obvious how to call win32gui.FindWindow yourself:
hwnd = win32gui.FindWindow(None, 'My Window Name')
And if you want a good explanation of the FindWindow/EnumWindows/etc. syntax, did you try looking at the docs for them? Is there something you didn't understand there?
Meanwhile:
… the classname of the window, which I don't know and haven't been able to find since it is just a game running in Java
What difference does it make that it's running in Java? You can enumerate the windows and print out their classnames, whether they're written in C++, Java, .NET, Python, or anything else. Or use one of the tools that comes with Visual Studio/VS Express, or any of the free improved versions you can find all over the net, like MS Spy++, which will let you point at a window and give you the caption and class name.
I don't want to enumerate the windows to find it as I'm not sure how that would work.
Just call windowmgr.find_window_wildcard(wildcard) with a regular expression, and it'll enumerate the windows and compare their titles to that regular expression.
If you want to write your own code to do it, just write a function like this:
def my_callback(hwnd, cookie):
Now, when you do this:
win32gui.EnumWindows(my_callback, some_cookie)
… it will call your my_callback function once per window, with hwnd being the window (which you can pass to win32gui functions like, e.g., GetWindowText), and cookie being the same some_cookie value you passed in. (If you don't need anything passed in, just pass None, and don't do anything with the value in your callback function. But you can see how the other answerer used it to pass the regular expression through.)
Meanwhile:
using find_window_wildcard as it's written in that script has managed to bring the window to the foreground a few times, but only if the window was already open, and it only works intermittently.
First, you can't bring a window to the foreground if it doesn't exist. How do you expect that to work?
As far as working intermittently, my guess is that there are lots of windows that match your wildcard, and the program is going to just pick one of them arbitrarily. It may not be the one you want. (It may even be a hidden window or something, so you won't see anything happen at all.)
At any rate, you don't need to use find_window_wildcard; if you know the exact name, use that. Of course it still may not be unique (whatever the game's name is, there's nothing stopping you from opening an email message or a Notepad window with the same title… which, by the way, is why you want to try class names first), but at least it's more likely to be unique than some underspecified wildcard.
So, what if the class name isn't unique (or, even worse, it's one of the special "number" classes, like #32770 for a general dialog window), and neither is the window name? You may be able to narrow things down a little better by looking at, say, the owning process or module (exe/dll), or the parent window, or whatever. You'll have to look through the win32gui and/or MSDN docs (linked above) for likely things to try, and play around through trial and error (remember the Spy tool, too) until you find some way to specify the window uniquely. Then code that up.

Windows Balloon-tooltips in Python

Following the example at http://article.gmane.org/gmane.comp.python.general/541418, I've succeeded in creating a callable class for balloon tooltips, but the greater complexities of that code elude me when it comes to customization. I browsed a bit of how it works through msdn, but being a novice at more windows-esque languagues like c and vb, etc. I was unable to make much sense of it.
So I ask ye snakely academics:
Things I'd like to be able to do with that code aside from the standard icon, title, text:
Perform actions based on clicking the tooltip
Modify the tooltip that pops up over the icon in the system tray after loading it (to reflect changing values)
Multiple lines? (Not sure if this can even be done, really)
More information on other things you could do in a windows 7 environment versus XP (which seems to be what this was written for).
Ideally I'd get some sort of return value or some semblance of an event when the tooltip is clicked so that I could run some code, but currently I'm importing that code as a module and calling at various times, so I'm not sure how to handle clicks outside of the popup code itself...
Information on handling these things with python seems quite scarce. Thanks in advance.
Perform actions based on clicking the tooltip
Whats the problem OnTaskbarNotify? Hock yourself in there.
Modify the tooltip that pops up over the icon in the system tray after loading it (to reflect changing values)
Probably not, I am not sure about the WinAPI here. I haven't seen it in the wild, so...
Multiple lines? (Not sure if this can even be done, really)
With most WinAPI, just insert a \n in the string.
More information on other things you could do in a windows 7 environment versus XP (which seems to be what this was written for).
LOTS... But that is a bit vague... It depends what your needs are. But for kol feturez you need to google on your own...
On Linux and Unix systems I use the notify-send OS already implemented system.
import os
os.system('notify-send "'+title+'" "'+message+'")
Maybe in Windows there is some API32 for this.
Check this https://gist.github.com/wontoncc/1808234

Double buffering with wxpython

I'm working on an multiplatform application with wxpython and I had flickering problems on windows, while drawing on a Panel.
I used to draw on a buffer (wx.Bitmap) during mouse motions events and my OnPaint method was composed of just on line:
dc = wx.BufferedPaintDC(self, self.buffer)
Pretty standard but still I had flickering problems on Windows, while everything worked fine on Linux.
I solved my problem calling SetDoubleBuffered(True) in the __init__ method.
The strange thing is that now everything works even if I don't use BufferedPaintDC anymore. I changed my application so that all the drawing part is done in the OnPaint method. I don't use a buffer and drawing is done directly on a wx.PaintDC with no flickering problems at all.
So my question is: is BufferedPaintDC totally useless? Or deprecated somehow? I'm owner of the book "WxPython in Action" (2006) and it doesn't even mention SetDoubleBuffered
There is a high probability that the SetDoubleBuffered actually makes your panel use a buffered dc automatically, the documentation doesn't mention that those classes are deprecated (and I rather think they would if that were the case).
About wxPython in Action... 2006 was a long time ago... it is possible that the SetDoubleBuffered method didn't exist back then or that the author wanted to show how things work at the lower level.

Categories