[PyKDE] QButton/QGridLayout woes

Hoka "ME" Tichenci melkin at uci.edu
Wed Sep 21 05:27:58 BST 2005


Switching to postEvent fixed the problem, thanks!

-Hoka

At 11:51 AM 9/20/2005, you wrote:

>If I interpret "the threaded object makes calls into my QT class"
>correctly, then this definitely could be the root of your problem.
>While you may have one thread dedicated to running the Qt Application
>object's event loop, the restriction documented by Trolltech
>restricts you from calling *any* of the Qt GUI API from another
>thread. That means that if your threaded object makes a call to your
>Qt class and that call results in any of the Qt API being invoked
>(which your example indicates that it does) then you aren't
>guaranteed proper behavior.
>
>The recommended method is to use QApplication:postEvent() (which is
>thread safe) to send an event to the Qt object that your threaded
>object is trying to manipulate. Then the QApplication's thread will
>deliver the event in the event loop and the operations you are trying
>to perform can be safely executed by QApplication's thread.
>
>Dave
>
>On Sep 20, 2005, at 1:07 PM, Hoka ME Tichenci wrote:
>
>
>>What I mean from a multithreaded application is that the threaded
>>object makes calls into my QT class, and the QT class modifies the
>>widgets accordingly (the qt app is single threaded). The given code
>>was within the QT application. Originally this didn't work because
>>the PyQT I was using was based on SIP3 (which caused lockups in
>>this exact scenario), but I should now be using a SIP4 release
>>(3.14.1 edu). I'm also using a locking mechanism so that this code
>>should run completely before it can be run again (so it should be
>>threadsafe). I think its odd because the message box will pop up if
>>I construct it, but trying to add the button doesn't work.
>>
>>-Hoka
>>
>>
>>
>>
>>>You mention "from a multithreaded application". Are you being careful
>>>to keep all Qt activity exclusively in one thread? From http://
>>>doc.trolltech.com/3.3/threads.html:
>>>
>>>----
>>>In Qt, one thread is always the GUI or event thread. This is the
>>>thread that creates a QApplication object and calls
>>>QApplication::exec (). This is also the initial thread that calls
>>>main() at program
>>>start. This thread is the only thread that is allowed to perform GUI
>>>operations, including generating and receiving events from the window
>>>system. Qt does not support creating QApplication and running the
>>>event loop (with QApplication::exec()) in a secondary thread. You
>>>must create the QApplication object and call QApplication::exec()
>>>from the main() function in your program.
>>>
>>>Threads that wish to display data in a widget cannot modify the
>>>widget directly, so they must post an event to the widget using
>>>QApplication::postEvent(). The event will be delivered later on by
>>>the GUI thread.
>>>----
>>>
>>>My guess would be that two threads got into Qt at the same time. It
>>>may not happen under Linux due to timing differences.
>>>
>>>Dave
>>>
>>>
>>>On Sep 18, 2005, at 10:07 PM, Hoka ME Tichenci wrote:
>>>
>>>
>>>
>>>
>>>>I'm having an odd issue with Windows PyQt 3.14.1 Educational, the
>>>>code is supposed to dynamically add/remove buttons when called from
>>>>a multithreaded application. On Linux (PyQt 3.13 qt 3.3.4) the code
>>>>runs fine, but on Windows I get assert problems in a rather odd
>>>>spot.
>>>>
>>>>The code is here (bgrid is a QGridLayout, bg_projectors is a
>>>>QButtonGroup):
>>>>print "adding projector rnode: %s" % rnode.getName()
>>>>attrs = rnode.getAttributes()
>>>>print "xpos: %s ypos: %s" % (attrs["xpos"],attrs["ypos"])
>>>>tmp = QPushButton(self.bg_projectors,"yes")
>>>>tmp.setText(rnode.getName())
>>>>print "qpushbutton built"
>>>>self.bgrid.addWidget(tmp,attrs["ypos"],attrs["xpos"])
>>>>print "widget added"
>>>>tmp.show()
>>>>print "Done adding projector!"
>>>>
>>>>However, when run I get this output:
>>>>
>>>>adding projector rnode: Projector: BigOne
>>>>xpos: 1 ypos: 1
>>>>qpushbutton built
>>>>projector is off
>>>>widget added
>>>>Done adding projector!
>>>>ASSERT: "src_dc && dst_dc" in kernel\qpaintdevice_win.cpp (388)
>>>>
>>>>What's odd is that the ASSERT failure is at the end, after the
>>>>method should be done and printed its last statement. Furthermore,
>>>>if I make a QWarningBox or other similar piece of code pauses the
>>>>system after tmp.show() is called, the QButton can be seen in the
>>>>background, after the box is closed the button disappears, but
>>>>oddly enough no ASSERT is thrown. This may not be the right way to
>>>>do something like this, and if it isn't correct me, but I'm at a
>>>>lost and Google didn't return anything worthwhile.
>>>>
>>>>Thanks for your time,
>>>>-Hoka
>>>>




More information about the PyQt mailing list