Re: running pyqt app event loop in secondary thread, using (Py)Qt6.5
Stefan Seefeld <[email protected]> Fri, 22 Sep 2023 13:53:54 -0400
| Newsgroups | gmane.comp.lib.qt.general,gmane.comp.python.pyqt-pykde |
|---|---|
| Message-ID | <CAOEGfx3s6fr4E79=q=Tvtq1ov+QXKdFH-bdMDhFMbs5YLLBNnA@mail.gmail.com> |
--===============7353355348582465267== Content-Type: multipart/alternative; boundary="00000000000066f2060605f64b74" --00000000000066f2060605f64b74 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Hi Jeremy, thanks for the quick reply ! On Fri, Sep 22, 2023 at 1:16=E2=80=AFPM Jeremy Katz <[email protected]> wr= ote: > > On 9/22/23 09:35, Stefan Seefeld wrote: > > > 1. run the above command, but click the "quit" button immediately. Thus > > results in the error message `QObject::killTimer: Timers cannot be > > stopped from another thread`, > > followed by a segmentation fault > > My guess is that the QApplication object is being destroyed by the > garbage collector, which isn't running in the QApplication's thread. > Adding an explicit `del self.app` after the QApplication.exec returns > prevents the crash for me. > Indeed, that works. (Unfortunately this approach is likely not to work in general, as pytest appears to be holding on to references in different places, making it highly unlikely that I can get the application's refcount down to 0 at a specific time / location in the code. Note that this is really just a test prototype I'm writing to understand the underlying issues a little better. The real test logic will use a QApplication that's exposed to Python using something other than sip (boost.python), and I'm considering ways to deliberately circumventing the reference counting, precisely so I can get back the control to delete the underlying Qt objects whenever I need to, rather than when the Python runtime would normally do it. > > This strategy likely won't work (AFAIK...) on macOS. While Qt is > relatively happy to run in any thread, the mac UI interface must be used > from the initial thread. > > > 2. rather than just "yielding" to the test function, yield the > > application object (so the test function can interact with it). No > > matter when you click the "quit" button, the result is the same as in 1= . > > > > 3. call `h.app.quit()` after he `yield` (i.e. as soon as the test > > function completes). Result: the application becomes unresponsive, but > > doesn't stop > > 2 and possibly 3 sound like more instances of a wrong thread situation. > The call to `quit()` is documented to be thread-safe, so it should work fine even when made programmatically from other threads than the one running the event loop. Is this potentially an issue with PyQt not routing the signal correctly ? Thanks, --=20 ...ich hab' noch einen Koffer in Berlin... --00000000000066f2060605f64b74 Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable <div dir=3D"ltr"><div dir=3D"ltr"><div>Hi Jeremy,</div><div>thanks for the = quick reply !<br></div></div><br><div class=3D"gmail_quote"><div dir=3D"ltr= " class=3D"gmail_attr">On Fri, Sep 22, 2023 at 1:16=E2=80=AFPM Jeremy Katz = <<a href=3D"mailto:[email protected]">[email protected]</a>> wrote:= <br></div><blockquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8= ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><br> On 9/22/23 09:35, Stefan Seefeld wrote:<br> <br> > 1. run the above command, but click the "quit" button immedi= ately. Thus <br> > results in the error message `QObject::killTimer: Timers cannot be <br= > > stopped from another thread`,<br> > followed by a segmentation fault<br> <br> My guess is that the QApplication object is being destroyed by the <br> garbage collector, which isn't running in the QApplication's thread= . <br> Adding an explicit `del <a href=3D"http://self.app" rel=3D"noreferrer" targ= et=3D"_blank">self.app</a>` after the QApplication.exec returns <br> prevents the crash for me.<br></blockquote><div><br></div><div><br></div><d= iv>Indeed, that works. (Unfortunately this approach is likely not to work i= n general, as pytest appears to be holding on to references in different pl= aces, making it highly unlikely that I can get the application's refcou= nt down to 0 at a specific time / location in the code.</div><div><br></div= ><div>Note that this is really just a test prototype I'm writing to und= erstand the underlying issues a little better. The real test logic will use= a QApplication that's exposed to Python using something other than sip= (boost.python), and I'm considering ways to deliberately circumventing= the reference counting, precisely so I can get back the control to delete = the underlying Qt objects whenever I need to, rather than when the Python r= untime would normally do it.<br></div><div><br></div><div>=C2=A0</div><bloc= kquote class=3D"gmail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left:= 1px solid rgb(204,204,204);padding-left:1ex"> <br> This strategy likely won't work (AFAIK...) on macOS. While Qt is <br> relatively happy to run in any thread, the mac UI interface must be used <b= r> from the initial thread.<br> <br> > 2. rather than just "yielding" to the test function, yield t= he <br> > application object (so the test function can interact with it). No <br= > > matter when you click the "quit" button, the result is the s= ame as in 1.<br> > <br> > 3. call `h.app.quit()` after he `yield` (i.e. as soon as the test <br> > function completes). Result: the application becomes unresponsive, but= <br> > doesn't stop<br> <br> 2 and possibly 3 sound like more instances of a wrong thread situation.<br> </blockquote></div><br clear=3D"all"><div>The call to `quit()` is documente= d to be thread-safe, so it should work fine even when made programmatically= from other threads than the one running the event loop.</div><div>Is this = potentially an issue with PyQt not routing the signal correctly ?<br></div>= <div><br></div><div>Thanks,<br></div><div><br></div><span class=3D"gmail_si= gnature_prefix">-- </span><br><div dir=3D"ltr" class=3D"gmail_signature"><d= iv dir=3D"ltr"><div><img src=3D"https://ci3.googleusercontent.com/mail-sig/= AIorK4yh4RzsqlxV6irScDGRVZ8a7NRCh_INtpPsAHx2Y8v4Vu3VKsI54RFNs3YRZk_2xTTtMMd= SCzdNrf5XRUlmF4BkezmtZv-j5c3A4G0hEA"></div><div><pre> ...ich hab' = noch einen Koffer in Berlin... </pre></div></div></div></div> --00000000000066f2060605f64b74-- --===============7353355348582465267== Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ Interest mailing list [email protected] https://lists.qt-project.org/listinfo/interest --===============7353355348582465267==--