Changing QLabel’s text through another process



  • I am using Python 2.5 and PyQt4.

    I have a QLabel in the main process. I fork a child process and I wish to share QLabel between Main and child processes. The child process should change the text of this label. I have tried the below code but I am unable to fetch and change the content of the shared variable in the child process...... Is there an alternative method to this (eg: passing the memory address of QLabel to the child process and let child process directly modify its contents) ?

    @def funct(arg):
    print 'arg: ',arg.value

    if name == 'main':
    app = QtGui.QApplication(sys.argv)
    label= QtGui.QLabel('some text')
    sharedvar=sharedctypes.RawValue(ctypes.py_object,label)
    pid = Process(target = funct, args=(sharedvar,))
    pid.start()
    pid.join()@



  • You have the possibility of using shared memory or a local socket to communicate: search for IPC in Qt Assistant. Processes are in independent virtual memory spaces, you cannot meaningfully shared the address of anything between them, but you could transfer the text of a message for example.



  • Short note:
    Using shared memory will not directly update the label
    You need some kind of message / IPC call or you must periodically check the shared memory for changes.
    A forked process has no access toe the parent variables.



  • Just to throw in my two pennies worth: Experience (and Google ;o) tells me that mixing PyQt's event loop and Pythons multiprocessing module tends to be a bad idea as they don't play nicely together. I'd suggest taking a look at either QThread (in which case you can use signal/slot to update your label) or QProcess and use one Qt's IPC techniques as described above (QLocalSocket/QLocalServer is quite nice for simple stuff, I've probably got an example somewhere too).



  • But again, QThread is implemented on top of python threads.... and python threads seem to consume more time. So, I went for multiprocessing.

    But I strongly feel that, I cant get my work done without using threads. Gerolf's solution seems to be the only answer at this point. I have dedicated a python thread which blocks on the shared memory. If there is an item in the shared memory, then this thread will use this item to update the main thread's label.
    It works well, but there is a small issue. Whenever I move the mouse over the label, then it throws this error message onto the console.
    @QApplication: Object event filter cannot be in a different thread@

    I guess this has got something to do with what jazzycamel has mentioned about combining PyQt's event loop and pythons threading/multiprocessing. Nevethless, I shall try using QThreads instead of python threads and see if this error message will disappear.



  • How are you updating the QLabel? You will need to use signal/slot to communicate between the shared memory thread and the main thread...

    @
    from PyQt4.QtGui import *
    from PyQt4.QtCore import *

    class Thread(QThread):
    update=pyqtSignal(str)
    def init(self, parent=None):
    QThread.init(self, parent)
    self.count=0

    def run(self): 
        self.tid=self.startTimer(1000)
        self.exec_()
    
    def timerEvent(self, event):
        self.count+=1
        if self.count==10: 
            self.killTimer(self.tid)
            self.exit(0)
        self.update.emit("%d" % self.count)
    

    class Widget(QWidget):
    def init(self, parent=None):
    QWidget.init(self, parent)

        l=QVBoxLayout(self)
        self.label=QLabel("0", self)
        l.addWidget(self.label)
    
        self.thread=Thread(self)
        self.thread.update.connect(self.label.setText)
        self.thread.start()
    

    if name=="main":
    from sys import argv, exit
    a=QApplication(argv)
    w=Widget()
    w.show()
    w.raise_()
    exit(a.exec_())
    @

    This example works fine without any warning messages.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.