Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Is this safe? Do I have to use signals to call UI widget methods?



  • Is this safe? Do I have to use signals to call UI widget methods on the main thread?

    import sys
    
    from PySide2.QtCore import QThread
    from PySide2.QtWidgets import QApplication, QWidget
    
    
    class MyThread(QThread):
        def __init__(self, main_window, *args, **kwargs):
            super().__init__(*args, **kwargs)
            self.main_window = main_window
    
        def run(self):
            # Is this safe? Do I have to use signals to call UI widget methods?
            print(self.main_window.geometry())
            # Is this safe? Do I have to use signals to call UI widget methods?
            self.main_window.hide()
            print(self.parent())
    
    
    if __name__ == '__main__':
        app = QApplication(sys.argv)
        my_widget = QWidget()
        my_widget.show()
        my_thread = MyThread(my_widget)
        my_thread.start()
        sys.exit(app.exec_())
    

    refer link:
    https://stackoverflow.com/questions/53058849/is-it-ok-to-read-qt-widgets-from-another-thread
    https://stackoverflow.com/questions/42876085/is-it-possible-to-hide-qt-widget-window-from-other-thread


  • Lifetime Qt Champion

    Hi
    No its not safe.
    Say your thread reads main_window.geometry() at the exact same time
    you resize the window and the main thread updates the info.

    Its best to use signals and slots for this.

    Else its just a crash waiting to happen.


  • Lifetime Qt Champion

    Hi
    No its not safe.
    Say your thread reads main_window.geometry() at the exact same time
    you resize the window and the main thread updates the info.

    Its best to use signals and slots for this.

    Else its just a crash waiting to happen.



  • Thanks. I understand. :-)


  • Banned

    Actually mrjj is wrong as technically that is totally safe because it simply will not work. This is because (while this is an assumption mind you) your main_window cannot be placed within a QThread in fact no object based on a QtWidget can be placed within a QThread nor can certain QtGui objects

    Next you do not sub-class a QThread, yeah I know that is probably still the official post documentation but it is absolutely wrong as that is how they did it in Qt4 and is not how its properly done in Qt5

    Next if it were to work yes it would be dangerous but not because of the Single/Slots but because you are using super( ) without handling the 3 issues it creates when its used. Still you ought not be using it since you are not using it for the very rare purpose it was created to handle. Aka super( ) is programmer-wanna-bes tool and anyone who knows programmer and fully understands the issues tied to using super( ) along with why it was created to begin with it would not use it at least 95% of the time.

    Next you should use QApplication([]) instead as if you are actually going to handle Command Line arguments you should be using the argparser library as it handles the Command Line arguments much more cleanly

    Next sys.exit(app.exec_()) is the Qt4 of doing this the Qt5 way is now simply app.exec()

    As a final note if you need help learning how to properly use QThreads just shoot me a PM as I conduct a free Python-Qt classroom where I tutor that as well as other quality programming methodologies


  • Lifetime Qt Champion

    @Denni-0 A QWidget can be placed in a QThread, but it is not supported and can lead to crashes and misbehaviour. And nothing stops you from calling methods on widgets from a non GUI thread (but of course you should not). So, @mrjj is not wrong.


  • Banned

    @jsulm you better re-read the documentation on QThreads (its buried in there somewhere) because I not only thoroughly read that documentation but I read it after I putting a QtWidget object into QThread and having it not work. So you are absolutely and completely wrong.

    P.S. Well okay you are minutely correct -- you can put a QtWidget object into a QThread but since it will not work when you do it is kind of like your claim - wrong and basically pointless.


  • Lifetime Qt Champion

    Technically: QWidget based objects should only be manipulated in the same thread where the QApplication object was created. Usually, it's in the main thread, the one created to run the "main" function but it can be another one although it's not the most used technique.


  • Banned

    Apparently none of you have actually tried to do this so instead of refuting me without knowledge of what actually is -- I challenge you go ahead create a secondary QThread in the proper method and try to display that QtWidget and see what your results are.

    Again I am not talking out of ignorance on this one as I was trying to do this when I discovered that my QtWidget object was not displaying than after much pain and research finally stumbled across the documentation that clearly states that you cannot put any QtWidget object (which means absolutely all of them) into anything but the Main Event Thread --- why well because (if I remember correctly) QThreads do not have an Event Handler so they will not function within a QThread -- this also effects some QtGui objects as well but I cannot say exactly which ones because I do not believe the documentation went into that detail.

    So to end this matter -- No you cannot per Qt put a QtWidget based object into a QThread and have it work as it should or at all for that matter. And again if you do not believe by all means create your own MUC and test it but please stop speaking out of ignorance and confusing folks who do not know. Oh and if you actually think you got a working version please post your MUC because my guess will be you did something and broke the Qt framework.


  • Lifetime Qt Champion

    Did you actually take the time to fully understand what I wrote ? At no point did I say that you could use a QWidget in a secondary thread beside the main thread, quite the contrary. I wrote that the thread creating the QApplication object was the only one where you are allowed to modify QWidget objects and that this precise thread might be a secondary thread even if it's not the common use case.


  • Banned

    @SGaist I did read your post -- twice -- I found it to be a bit confusing but it appeared you were contradicting that a QtWidget object could not be run in a QThread -- if I missed interpreted your comment I apologize however your clarafied statement I still find extremely confusing so let me unpack it.

    First off a QWidget is a QtWidget object and I said all QtWidget objects which would include the QWidget cannot be run in a QThread -- minor point I agree but I am unpacking this for clarity

    Next the QApplication is not just A Thread -- it is what Qt refers to as the Main Event Handler which makes it much more than just a QtWidget object and it itself is not actually thread although I agree it acts like one in many ways it is simple a lot more.

    Next the QApplication cannot be a secondary thread as it is always the primary aka Main -- Event Handler and further does not operate within a QThread but operates within a Process so it cannot exist within a "secondary thread" or any thread for that matter -- it can only exist within a Process -- again a fairly fine line since a process is a sort of Thread but also more and this more part is a very significant one thus important to denote in order to avoid confusion.

    This is why I found your first and clarification posts to be confusing -- and clarity in this issue is paramount as the distinctions are significantly important to creating a proper functioning program and to keep from confusing folks who may not be as versed in the nuances of the functionality of python-qt


  • Lifetime Qt Champion

    This post is deleted!

Log in to reply