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

WebView crashes when setUrl is called inside a thread



  • Hi. I am building an application using pySide2 and I notice a problem that occures:

    1. Only when the operation is inside a thread
    2. Only when the operation calls the method setUrl and some other webview methods

    The process is the following:

    1. A client sends signals (1, 2, 3..etc)
    2. My application handles the signals and matches each number with an appropriate url
    3. Url should be shown to the screen and wait for a new signal

    Question: The application does not work as intended. Instead of showing a new url, the application just terminates without any exception thrown. Why is this happening and how can I fix it? Thanks in advance

    Some implementations regarding this issue.

    # Execute a new thread that listens to socket
    worker = Worker(self.server_listen_respond, QUrl('http://www.google.com/'))
    
    # Start thread
    self.threadpool.start(worker)
    
    # Thread
    def server_listen_respond(self):
    
        # Thread operations apply here....
    
    # ...After some checks a function is called (Slightly simplified)
    def change_screen(self):
        self.ui.lblUrl.setText('Changed to url' + ' google')
    
        # On the following expression, the program just terminates 
        self.ui.webView.setUrl(QUrl("http://www.google.com"))
    

  • Lifetime Qt Champion

    Hi and welcome to devnet,

    One simple rule to follow:
    Do not access GUI elements from a different thread than the GUI thread.

    Use signals and slots to transfert the data.



  • @SGaist

    Hi and thank you so much for your response

    What do you mean? How should I modify my code? Can you give me an example?


  • Lifetime Qt Champion

    What is your worker class ?

    Here you have the documentation about the signals and slots concept.



  • @SGaist

    Below is my working class with the name Worker(QRunnable)

        def __init__(self, fn, *args, **kwargs):
            super(Worker, self).__init__()
            self.fn = fn
            self.args = args
            self.kwargs = kwargs
    
        @Slot()
        def run(self):
            '''
            Initialize the runner function with passed args, kwargs.
            '''
            self.fn(*self.args, **self.kwargs)
    

    When executing the two expressions below, The function server_listen_respond is executed. Inside that function I am trying to change the webview's Url....but it crashes

    worker = Worker(self.server_listen_respond, some_init_url)
    self.threadpool.start(worker)
    

  • Lifetime Qt Champion

    So you are still accessing a GUI element from a different thread ? As I already wrote, you can't do that.



  • @SGaist You asked me for my worker class that's why I sent it to you. I thought it was possible though. How you propose to change my code? Cause I am confused :(

    Right now I am trying to follow your advice. I try to implement signals and slots, however I am new to this and it doesn't seem to work.

    Edit: Thanks! I actually had made a false connection between signal and slot!
    Here is what I did!

    1. Inside QMainWindow
    signal_change_movement = Signal(str)
    
    def __init__(self):
        self.signal_change_movement.connect(self.change_url)
    
    1. Inside thread
    # Inside thread
    self.signal_change_movement.emit('https://forum.qt.io/')
    

  • Lifetime Qt Champion

    Before diving deeper in that:

    • Why do you need that secondary thread ?
    • What experience do you have with threading ?
    • What experience do you have with signals and slots ?


  • @SGaist

    1. Because I initialized a socket connection and I want to be able to mess around with the QMainWindow, and at the same time listen for incoming requests & responses
    2. I did a course in university about parallel programming
    3. Absolutely none :)

  • Lifetime Qt Champion

    1. I highly encourage you to learn the signals and slots paradigm.

    2. Qt is an asynchronous framework which means that you may not need an additional thread depending on what you need to process and how you process it.

    3. Did they warm you about the nuclear footgun that it can be ? ;-)