[PyQt] QObject: Cannot create children for a parent that is in a different thread. How to edit another threads objects?

Jason H scorp1us at yahoo.com
Tue Sep 15 01:41:01 BST 2009


Qt can pass its "fundamental types" across threads - and use them in signals/slots.

You can only access/manipulate GUI elements in the main thread. Use a signal/slot between the two threads and have the slot in the main thread update the GUI. Your line for the  ******* line should be an emit.




----- Original Message ----
From: Soumen banerjee <soumen08 at gmail.com>
To: pyqt at riverbankcomputing.com
Sent: Monday, September 14, 2009 8:27:42 PM
Subject: Re: [PyQt] QObject: Cannot create children for a parent that is in a  different thread. How to edit another threads objects?

I cant understand what im doing wrong. Heres the code
gui.py:
from PyQt4 import QtCore, QtGui
import sys
from subprocess import Popen
class Ui_MainWindow(object):
    fileinit=False
    paused=True
    quit=False
    filename=""
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(394, 414)
        self.centralwidget = QtGui.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.scrollArea = QtGui.QScrollArea(self.centralwidget)
        self.scrollArea.setGeometry(QtCore.QRect(19, 9, 361, 281))
        self.scrollArea.setWidgetResizable(True)
        self.scrollArea.setObjectName("scrollArea")
        self.scrollAreaWidgetContents = QtGui.QWidget(self.scrollArea)
        self.scrollAreaWidgetContents.setGeometry(QtCore.QRect(0, 0, 357, 277))
        self.scrollAreaWidgetContents.setObjectName("scrollAreaWidgetContents")
        self.textEdit = QtGui.QTextEdit(self.scrollAreaWidgetContents)
        self.textEdit.setGeometry(QtCore.QRect(-7, -6, 371, 291))
        self.textEdit.setObjectName("textEdit")
        self.scrollArea.setWidget(self.scrollAreaWidgetContents)
        self.pushButton = QtGui.QPushButton(self.centralwidget)
        self.pushButton.setGeometry(QtCore.QRect(30, 310, 80, 25))
        self.pushButton.setObjectName("pushButton")
        self.pushButton_2 = QtGui.QPushButton(self.centralwidget)
        self.pushButton_2.setGeometry(QtCore.QRect(139, 310, 91, 25))
        self.pushButton_2.setObjectName("pushButton_2")
        self.pushButton_3 = QtGui.QPushButton(self.centralwidget)
        self.pushButton_3.setGeometry(QtCore.QRect(280, 310, 80, 25))
        self.pushButton_3.setObjectName("pushButton_3")
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtGui.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 394, 23))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtGui.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        QtCore.QObject.connect(self.pushButton, QtCore.SIGNAL("clicked()"), self.Open)
        QtCore.QObject.connect(self.pushButton_2,
QtCore.SIGNAL("clicked()"), self.Pause)
        QtCore.QObject.connect(self.pushButton_3,
QtCore.SIGNAL("clicked()"), self.Quit)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        MainWindow.setWindowTitle(QtGui.QApplication.translate("MainWindow",
"MainWindow", None, QtGui.QApplication.UnicodeUTF8))
        self.pushButton.setText(QtGui.QApplication.translate("MainWindow",
"Open", None, QtGui.QApplication.UnicodeUTF8))
        self.pushButton_2.setText(QtGui.QApplication.translate("MainWindow",
"Pause/Resume", None, QtGui.QApplication.UnicodeUTF8))
        self.pushButton_3.setText(QtGui.QApplication.translate("MainWindow",
"Quit", None, QtGui.QApplication.UnicodeUTF8))
    def Pause(self):
        print "Pause"
        self.paused=not(self.paused)
    def Quit(self):
        self.quit=True
        print "setting quit"
    def Open(self):
        print "Open"
        self.filename=QtGui.QFileDialog.getOpenFileName()
        self.filename=str(self.filename)
        try:
            f=open("book.txt","r")
        except IOError:
            f=open("log.txt",'w')
            f.write('0')
            f.close()
        old=f.read(20)
        f.close()
        f=open(self.filename,'r')
        new=f.read(20)
        f.close()
        if(old!=new):
            f=open("log.txt",'w')
            f.write('0')
            f.close()
            f=open("book.txt",'w')
            f.write(new)
            f.close()
        self.fileinit=True
        print "setting fileinit"
        
and heres the main.py

from PyQt4 import QtCore, QtGui
import sip,gui
import sys
from subprocess import Popen
from threading import Thread
class AppThread(Thread):
    appinit=False
    def run(self):
        self.app = QtGui.QApplication(sys.argv)
        MainWindow = QtGui.QMainWindow()
        self.ui = gui.Ui_MainWindow()
        self.ui.setupUi(MainWindow)
        MainWindow.show()
        self.appinit=True
        sys.exit(self.app.exec_())
class Speak(Thread):
    def run(self):
        print "starting speaker"
        try:
            log=open("log.txt",'r')
            print log
            self.index=log.read()
            log.close()
            self.index=int(self.index)
        except IOError:
            print "setting new"
            index=0
#by now, index has been defined for both a new and an old book
        self.book=open(a.ui.filename,'r')
        self.book.seek(self.index)
        while(a.ui.quit==False):
            if (a.ui.paused==False):
                sen=self.readsen()
********            a.ui.textEdit.setText(sen)
                command="soundwrapper espeak "+' " '+sen+' " '
                k=Popen(command,shell=True)
                k.wait()
        print "quitted loop"
        index=self.book.tell()
        log=open("log.txt","w")
        log.write(str(index))
        log.close()
        print "calling exit"
        a.app.exit()
        sys.exit()
    def readsen(self):
        line=""
        sen=""
        while(line.find(".")== -1):
            sen=sen+line
            line=self.book.readline()
        sen=sen+line[0:line.find(".")+1]
        self.book.seek(self.book.tell()-len(line)+line.find(".")+1)
        return sen
a=AppThread()
a.start()
while 1:
    if a.appinit== True:
        if a.ui.fileinit==True:    
            s=Speak()
            s.start()
            break

Look at the line with many stars at the left. Is that an incorrect way
of calling the setText method of the textEdit in the other thread?
Pls Help,
Regards
Soumen
_______________________________________________
PyQt mailing list    PyQt at riverbankcomputing.com
http://www.riverbankcomputing.com/mailman/listinfo/pyqt



      


More information about the PyQt mailing list