I've got this cool widget I'm working on and I simply want to paint this central straight line, over the slider widget that I've created.
Since the PaintEvent activates at initialization, anything called in the main class is displayed above the painted lines. With this in mind, can I call a paintevent function to initialize after my slider widgets have already been called/initialized?
Moreover, would it be smart to use threading.event() to stall the paint event function until after these sliders have been called, when I set the event?
Any advice would be great
*** UPDATE ***
event.is_set() blocking doesn't have an effect and the painter still paints below the QAbstractSlider
I am showing a user a popup menu when they right click.
According to the popup behaviour, I want to destroy the popup when it looses focus(when user clicks outside the popup window). For that I tried to connect the popup window to "focus-out-event", using Glade. But for some reason, that event is not getting fired. I tried to print something on the terminal when the event is fired, but nothing gets printed.
I am new to Python and GTK, and now I have no clue how to proceed further.
#handler to catch the focus out event
def on_popup_menu_add_attachment_focus_out_event(self, *args):
print("Destroying the popup.....")
focus-out-signal and its handler
I just changed the Type as Top Level and it worked!
I'm currently need GUI library for a project. I'm familiar with python and found PyQt might be a good choice.
I'm reading a tutorial about PyQt, and quite confused about the following example program
#!/usr/bin/python
# -*- coding: utf-8 -*-
"""
ZetCode PyQt4 tutorial
In this example, we draw text in Russian azbuka.
author: Jan Bodnar
website: zetcode.com
last edited: September 2011
"""
import sys
from PyQt4 import QtGui, QtCore
class Example(QtGui.QWidget):
def __init__(self):
super(Example, self).__init__()
self.initUI()
def initUI(self):
self.text = u'\u041b\u0435\u0432 \u041d\u0438\u043a\u043e\u043b\u0430\
\u0435\u0432\u0438\u0447 \u0422\u043e\u043b\u0441\u0442\u043e\u0439: \n\
\u0410\u043d\u043d\u0430 \u041a\u0430\u0440\u0435\u043d\u0438\u043d\u0430'
self.setGeometry(300, 300, 280, 170)
self.setWindowTitle('Draw text')
self.show()
def paintEvent(self, event):
qp = QtGui.QPainter()
qp.begin(self)
self.drawText(event, qp)
qp.end()
def drawText(self, event, qp):
qp.setPen(QtGui.QColor(168, 34, 3))
qp.setFont(QtGui.QFont('Decorative', 10))
qp.drawText(event.rect(), QtCore.Qt.AlignCenter, self.text)
def main():
app = QtGui.QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
Here, in main function, an Example object is created, thus __init__() function, initUI() is called.
My question is where does paintEvent() function is called?? since if we run the program, self.text(some Russian letters) will exactly appear on the widget.
In other words, what does sys.exit(app.exec_()) actually do? why it will call paintEvent() function?
Thanks!
From PyQt docs:
int QApplication.exec_ ()
Enters the main event loop and waits until exit() is called, then
returns the value that was set to exit() (which is 0 if exit() is
called via quit()).
It is necessary to call this function to start event handling. The
main event loop receives events from the window system and dispatches
these to the application widgets.
From another source:
sys.exit(app.exec_())
Finally, we enter the mainloop of the
application. The event handling starts from this point. The mainloop
receives events from the window system and dispatches them to the
application widgets. The mainloop ends, if we call the exit() method
or the main widget is destroyed. The sys.exit() method ensures a clean
exit. The environment will be informed, how the application ended.
The exec_() method has an underscore. It is because the exec is a
Python keyword. And thus, exec_() was used instead.
About painting:
4.2.1. When Painting Occurs
The paintEvent() method is called automatically when
Your widget is shown for the first time.
After a window has been moved to reveal some part (or all) of the
widget.
The window in which the widget lies is restored after being minimized.
The window in which the widget lies is resized.
The user switches from another desktop to the desktop on which the
widget's window lies.
You can generate paint events manually by calling QWidget::update().
QWidget::update() erases the widget before generating the paint event.
You can pass arguments to update(), which can restrict painting only
to areas (rectangles, in particular) that need it. The two equivalent
forms of the method are QWidget::update (int x, int y, int width, int
height) and QWidget::update (QRect rectangle), where x and y give the
upper-left corner of the rectangle, and width and height are obvious.
Because update() places a paint event into the event queue, no
painting occurs until the current method exits and control returns to
the event handler. This is a good thing because other events may be
waiting there to be processed, and events need to be processed in a
timely manner for the GUI to operate smoothly.
You can also invoke painting of the widget by calling QWidget::repaint (int x, int y, int width, int height, bool erase) (or one of several
convenience-method forms), where all the arguments mean the same as in
the case of the update() method, and erase tells repaint whether to
erase the rectangle before painting it. repaint() calls paintEvent()
directly. It does not place a paint event into the event queue, so use
this method with care. If you try to call repaint() repeatedly from a
simple loop to create an animation, for example, the animation will be
drawn, but the rest of your user interface will be unresponsive
because the events corresponding to mouse button clicks, keyboard
presses, and so on will be waiting in the queue. Even if you are not
performing a task as potentially time-consuming as animation, it is
generally better to use update() to help keep your GUI alive.
If you paint something on your widget outside the paintEvent(), you
still need to include the logic and commands necessary to paint that
same thing in paintEvent(). Otherwise, the painting you did would
disappear the next time the widget is updated.
It becomes more clear when one has some experience with low level programming,
for example in Winapi or the X toolkit in C language. PyQt is a (very) high level toolkit.
It comes with a huge built-in functionality. Similar example would require hundreds or maybe thousands of lines of C code. As a consequence, there is a lot of going on
behind the scenes. Somebody already created code that deals with painting on a basic level.
GUI programming is very complex and with modern GUI toolkits the application programmer is shielded from this complexity. It is inevitable that programmers are confused if they do not know all the technical details.
In PyQt, we are essentially dealing with events in two ways. We connect signals to slots or reimplement event handlers (an event handler is a synonym for a slot). The provided example inherited from the QtGui.QWidget which already has some painting code available.
In order to do our custom painting, we have to reimplement the existing paintEvent() event
handler. Depending on the situation, we may or may not call the parent's paintEvent() method.
The sys.exit(app.exec_()) does not call the paintEvent() method. The exec_() method starts an event loop. The event loop catches and dispatches events. Paint events are triggered by users or by the operating system. For example, when we launch the example, the
paint event is triggered twice. (Put a print "Event occurred" line in the event handler to see how many times this method is called.) Resizing windows, loosing or gaining focus, minimizing or maximizing windows, all these cause painting events to be triggered.
app.exec_() starts the qt main loop, which ends when every created widget is destroyed (e.g. by closing its window). The paintEvent function is a method that you can overload from a QWidget subclass like the given Example class, which gets called when QT displays, updates or repaints the Widget.
You can look up these things in the Qt documentation or the PyQt Documentation (which is mostly just a copy of the QT Documentation in a different format, but sometimes contains some valuable information regarding PyQt-specific things).
Problem: I have a gtk.Dialog. Whenever the 'minimize' button on the dialog is clicked, the window is destroyed.
Question: How can I connect to the minimize button of a gtk.Dialog so that I can iconify the window?
Are you sure it's the minimize button? Because GTK doesn't deal with (or even know about the existence of) minimize buttons at all, they are part of the window manager.
I have created a margin in a gtk.TextView widget. Now I want to make sure that the default event handler for mouse click, which is moving the text cursor to the clicked position, works only when clicked to the right of the margin.
Is this possible?
Try connecting to the button-press-event but doing it before the widget's own connection. If you connect after the view does it, this will be the default (GObject signal handlers are handled in reverse order of connection by default). Then determine if the event should be let through or not, by returning TRUE (to stop the event) or FALSE as required.