Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PyQt: updating GUI from a callback

Using Python3 and PyQt4 I have a function (run) that takes as an input a callable to provide status updates.

class Windows(QtGui.QWidget):
    # Creates a widget containing:
    # - a QLineEdit (status_widget)
    # - a button, connected to on_run_clicked

    def on_run_clicked(self):
        def update(text):
            self.widget.setText(text)

        threading.Thread(target=run, args=(update, )).start()

This works ok (i.e. the text updates are displayed properly in the widget). However, when I replace QLineEdit by QTextEdit and use the append method to add text, I get:

QObject::connect: Cannot queue arguments of type 'QTextCursor'

(Make sure 'QTextCursor' is registered using qRegisterMetaType().)

It still works but point to the fact that I am doing something wrong, and I am not sure that I will keep working when more threads are active. Usually, I do this type of updates using signals and slots, but the run function is not PyQt specific. The questions are:

  1. Why does it work without a warning for QLineEdit and not for QTextEdit?
  2. What is the right way to deal with a situation like this?
like image 411
Hernan Avatar asked Aug 23 '12 00:08

Hernan


People also ask

Why use PySide instead of PyQt?

Advantages of PySide PySide represents the official set of Python bindings backed up by the Qt Company. PySide comes with a license under the LGPL, meaning it is simpler to incorporate into commercial projects when compared with PyQt. It allows the programmer to use QtQuick or QML to establish the user interface.

Is PyQt better than PySide?

PyQt is significantly older than PySide and, partially due to that, has a larger community and is usually ahead when it comes to adopting new developments. It is mainly developed by Riverbank Computing Limited and distributed under GPL v3 and a commercial license.

Is PyQt good for GUI?

PyQt is a Python binding for Qt, which is a set of C++ libraries and development tools that include platform-independent abstractions for Graphical User Interfaces (GUI), as well as networking, threads, regular expressions, SQL databases, SVG, OpenGL, XML, and many other powerful features.

What is QtGui in PyQt5?

The QtGui module contains classes for windowing system integration, event handling, 2D graphics, basic imaging, fonts and text. It also containes a complete set of OpenGL and OpenGL ES bindings (see Support for OpenGL).


1 Answers

I don't know the specific reason why one class works and the other doesn't - nor do I really know the difference between using Python threading vs. Qt's threading...however, I can tell you that it is very tempremental if you don't set it up properly. Namely, you cannot (or at the very least, should not) modify GUI objects from a thread. Again, not sure the difference of a python vs. a Qt thread on that. But, the safe way to modify your interface from a GUI is by sending signals to your window...easiest way I know to do this is via the Qt threading.

class MyThread(QtCore.QThread):
    updated = QtCore.pyqtSignal(str)

    def run( self ):
        # do some functionality
        for i in range(10000):
            self.updated.emit(str(i))

class Windows(QtGui.QWidget):
    def __init__( self, parent = None ):
        super(Windows, self).__init__(parent)

        self._thread = MyThread(self)
        self._thread.updated.connect(self.updateText)

        # create a line edit and a button

        self._button.clicked.connect(self._thread.start)

    def updateText( self, text ):
        self.widget.setText(text)
like image 91
Eric Hulser Avatar answered Oct 17 '22 03:10

Eric Hulser