I'm programming (in python) GDK without GTK, simply as a x11 abstraction. THIS POST IS MY LAST CHANCE.
My problem is that I don't know how capture the GDK window's signals/events or what are their names.
When I do:
window = gdk.Window(
gdk.get_default_root_window(),
width=400,
height=200,
window_type=gdk.WINDOW_CHILD,
wclass=gdk.INPUT_OUTPUT,
event_mask=gdk.KEY_PRESS_MASK | gdk.MOTION_NOTIFY | gdk.EXPOSURE_MASK)
window.connect("key_press_event", on_key)
I get:
unknown signal name: key_press_event
GTK and PYGTK references talk about classes, functions and constants but nothing about their interrelation so they don't help.
Is it about glib main loop?
I need some examples. Any good GDK tutorial or source code? Any glib.MainLoop example for capturing GDK signals?
Thank you.
You can use gdk_event_handler_set to set the event handler (which is also the function used by gtk). Don't know which python binding u r using but I think you can easily find the corresponding python function. (In gi, it's simply Gdk.Event.handler_set)
You can check here for an example (There is also a non-block example). Although they are in C.
You're trying to connect to key-press-event, which is a gtk.Widget signal. gdk.Window doesn't inherit from gtk.Widget, so it doesn't have that signal.
In the GTK documentation, the little sections near the top labeled "Object Hierarchy" tell you how the classes relate together. There isn't really such thing as a GDK tutorial since one hardly ever uses it without GTK. I don't think it's very useful to do so either. Perhaps you can elaborate on what you are trying to achieve?
Related
I wrote a program using Qt 4.8, which used the QX11Embed mechanism to embed a useful little python/gtk widget.
I forked the widget, got its winID and then embedded it in a Qt container widget. This worked well
Then I had to change to Qt5 and the whole QX11Embed code has been dropped:(
Apps that take a winID as a commandline arg and embed into it, like mplayer or xterm, still work with Qt5. You just create a container, pass its winID to the app, but not the other way around.
I am not a python programmmer, but even so I am considering changing the widget itself so that it embeds itself into a given winID, but I cannot find any examples or docs.
Every search that mentions embedding goes to the plug/socket mechanism for embedding INTO gtk, nothing the other way around.
How should I go about it, is it even possible, any links etc
Thanks
I'm trying to use GTK3 and Cairo from Python for a minimal plotting application where the on-screen display of Cairo's output is for user convenience.
The typical usage is that I run a command, a plot pops up on screen and is also written to file, and I want to be able to dismiss the window as quickly as possible, ideally just a "q" keypress but also the common Ctrl-W and Ctrl-Q in addition to the default Alt-F4 (does anyone really use that regularly?!?).
I also want as little UI clutter in the window as possible: ideally just the standard window surround, no menus, toolbars, etc.
So... how can I bind my "q", "Ctrl-Q", etc. keybindings to Gtk.main_quit without having to a) create a cluttersome drop-down menu bar and b) go though the heavyweight Gtk.UIManager focused on by the Python Gtk+ 3 documentation here: http://python-gtk-3-tutorial.readthedocs.org/en/latest/menus.html . I hope this is possible, and doesn't require a lot of code (at least not as much as to set up all the menus!), but I can't find an example anywhere online: maybe I'm just searching for the wrong terms, being a GTK newbie.
Unfortunately there doesn't seem to be any documentation on making such a minimal accelerator setup, and the code to configure accelerator keys seems to differ a great deal between GTK2 and 3... thanks for helping.
Connect a signal to your main frame Win.connect('key-press-event', self.on_key_function) and in on_key_function (self, widget, event) check the value of event.keyval. For ESC is 65307 if you like hardcoded. Also, for key combinations, event.state report shift, alt(meta), and so on: if Gdk.ModifierType.CONTROL_MASK & event.state:do_something if ctrl is pressed
You could have separate stataments for left-ctrl, right-alt; be sure not to try to capture predefined key combinations, thay may be consumed by window manager.
A IDE with a good introspection will help you a lot, just write Gdk (previously imported) and autocompletion will popup a lot of functions/clases, most of them with a self-explanatory name.
Don't use key-press-event and keyval, it won't work for users with non-Latin keyboard layouts. GTK+ does a great job internally to match keyvals to hardware keys, this functionality is exposed via accelerators (often shortened as accel in the API) and bindings.
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.
Maybe I'm jumping into the deep end, but I'll give it a shot.
Here are some useful features of Tkinter:
The Tkinter Canvas widget is an object oriented drawing canvas. The elements of the drawing are essentially widgets themselves, as they can be moved, modified, and bound to events.
Tkinter uses bindings to trigger callbacks. The event is passed as a string. Custom events can be easily created with event_generate.
Tkinter has the after method, which waits for a specified amount of time without freezing the GUI.
Tkinter has predefined fonts like TkDefaultFont, and colors like systemButtonFace, which are dependant on the system.
My questions are:
What are the pyQt equivalents of these features (especially the bold ones)?
How can I "bind" elements of a widget (e.g. the label of a checkbutton only) to an event?
In Qt and PyQt events are called signals and you bind to them using slots (docs here). Generally speaking what you do define a slot with an # decorator.
class WindowImpl (QtGui.QMainWindow, Ui_TremorMain, Ui_Graphs):
def __init__ (self, buffer, parent = None, configuration = None):
# do some initialisation here (not GUI setup however)
#QtCore.pyqtSlot(int, name="on_confSelectorCombo_currentIndexChanged")
def confChanged (self, newConf):
# do some stuff here to handle the event
The above would be triggered on the currentIndexChanged event of an object called confSelectorCombo. The setup of the confSelectorCombo is done in the GUI builder or Qt Creator as Nokia has decided to call it. This really is what you want to use to get started. There's tutorials here on using Qt Creator. Obviously you'll want to go through the docs and see what signals are emitted by which widgets.
As for the font stuff all I know is what it says on the docs:
If you have not set a font for your application then the default font on your
machine will be used, and the default font can be different on different
machines. On Windows the default Windows font is used, on X11 the one in qtrc
can be used. If a default font can’t be found, then a font specified by Qt
will be used.
The QStyleSheet and QStyle act as proxies for changing the appearance of widgets (QStylesheet,QStyle).
As for making the application wait I found this
QTime dieTime = QTime::currentTime().addSecs(2);
while( QTime::currentTime() < dieTime ):
QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
There is also QThread.sleep() (docs), depending on what kind of an effect you want. Probably also worth looking at the threading support over at Qt docs
Overall in finding information about how to do stuff in PyQt I have found it surprisingly useful to look at the Qt documentation and then just writing the stuff in Python. 9 times out of 10 this works. On another note, it's probably also worth looking into PySide which is another python Qt library. I've haven't used myself before as it has been in the works previously but I noticed that they had released a 1.0.6 version.
UPDATE
Just to reiterate Luke Woodward below, you can use QGraphicsScene and QGraphicsView to render stuff in an object oriented way. The QGraphicsScene doesn't actually render anything it just a scene graph, the QGraphicsView is then used to render the contents of the scene graph. For low level drawing there´s also QPainter - there's a basic drawing tutorial here. It's also worth looking at QGraphicsItem which is the base for all graphics items and
includes defining the item's geometry, collision detection, its painting
implementation and item interaction through its event handlers
docs here. The Context2D provides an HTML canvas (if I'm not mistaken through the use of WebKit). The canvas itself only has a changed slot, but any objects you place on the canvas will/can have more slots. There's a fairly complete looking tutorial on Context2D and Context2DCanvas here. For an explanation as to why so many different ways of rendering stuff, you'll have to ask someone else. My two cents is that is has something to do with the fact that Qt is supposed to work everywhere and Trolltech and later Nokia wanted to provide lots of choice. Luckily the docs are really good.
I'm a new in Python.
I would like to know can I create good interface on python, something like WPF?
I didn't find any glass effect with PyQt. It's really important for my decision.
Thanks.
I'm sorry that I didn't give a lot of details. I need to port WPF app to python. The main goal I still need a good UI. Can I make something like this
http://www.codeproject.com/KB/silverlight/SilverlightGlassOrbButton.aspx?msg=3170079
on python? Can I use different styles for mouseover and normal state?
Glass effect is probably a Qt skin and has nothing to do with Python in particular. People say that there's a tutorial for Qt skinning. I failed to quickly google a ready-made glass-like skin, though.
Also, in the new QT RC there is a new support system for GUI related stuff. QML it is called, and examples can be found here. I do not know if it alreade wrapped in PyQT but I suppose it is possible to use it in combination with PyQT.
If glass effect = transparency, then Qt supports this, but it requires a special flag set on the window. See http://doc.qt.nokia.com/qq/qq16-background.html for some examples.
If you want a blurred background, then I doubt it can be done as easily, since not many GUI-frameworks that Qt supports do compositing like Vista & Win7, so it's probably hard to abstract into a cross-platform toolkit.
But simpler things might be possible, and with QGraphicsScene, you can do a lot of these things yourself (but not w.r.t. the window's background, IIUC).
If you have no luck with Qt, wxPython can do it. See How to draw a transparent frame in wxpython.
You can check out the fluent app library