On Sunday 17 October 2010, 19:04:16 Janwillem van Dijk wrote:
I want the output of a function that runs in a thread to be shown in
a QPlainTextEdit on the main window. Now this crashes with a message
that I sould use qRegisterMetaType. There are dozens of entries on
the web on this but I could not find any that tells how to. At least
not how to in python.
My handicap is that I have not too much experience with
oo-programming and none at all with c++. Thus suggestions like call
qRegisterMetaType() to register the data type before you establish
the connection. are of no help and I have no idea what to make of
things like qRegisterMetaTypeVolumeType( VolumeType );
This isn't possible is PyQt anyway, but these are signs of you doing
something fundamentally wrong here.
Please can someone tell me what to do with the small example below to
get it working.
Please read the text: Reentrancy and Thread-Safety in Qt's
documentation and use the back and forth links to explore this topic to
some extend. 98% of what is said there is applicable to PyQt, too.
The example, that your code refers to did it right by using signals and
slots to communicate between the main thread and the worker thread. You
are not allowed to access widgets directly.
BTW, your example isn't runnable since your ui file is missing.
#!/usr/bin/python
Small test application for threaded output to a QPlainTextEdit.
The main window consists of three buttons and the QPlainTextEdit
- pressButtonInsert clicked is connected to slotInsert: append text
to the edit widget
- pressButtonThread clicked is connected to slotInsertThreaded:
append text to edit widget from within a separate thread
- pressButtonClear clicked is connected to slotClear: clear the edit
widget
import sys, time
from PyQt4 import QtCore, QtGui
from qPlainTextEditGui import Ui_Form #the main form containing the 4
widgets
class MyForm(QtGui.QMainWindow):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.ui = Ui_Form()
self.ui.setupUi(self)
def slotClear(self):
print('ButtonClear triggered')
self.ui.plainTextEdit.clear()
def slotInsert(self):
print('ButtonInsert triggered')
append_to_edit(self.ui.plainTextEdit)
def slotInsertThreaded(self):
print('ButtonTreaded triggered')
self.work = work_thread(self.ui.plainTextEdit)
^
Bad idea starts here
self.work.start()
class work_thread(QtCore.QThread):
After
http://joplaete.wordpress.com/2010/07/21/threading-with-pyqt4/
def __init__(self, edit, parent=None):
QtCore.QThread.__init__(self, parent)
self.edit = edit
def run(self):
append_to_edit(self.edit)
def append_to_edit(edit):
for i in range(5):
edit.appendPlainText('line %d' % i)
^^^
*Bang*
time.sleep(0.5)
bad style, better use QThread.msleep()
if __name__ == __main__:
app = QtGui.QApplication(sys.argv)
myapp = MyForm()
myapp.show()
sys.exit(app.exec_())
Now it works fine when pressButtonInsert is triggered but returns
this when pressButtonThread is triggered:
QObject::connect: Cannot queue arguments of type 'QTextBlock'
(Make sure 'QTextBlock' is registered using qRegisterMetaType().)
QObject::connect: Cannot queue arguments of type 'QTextCursor'
(Make sure 'QTextCursor' is registered using qRegisterMetaType().)
Many thanks for helping me out,
Janwillem
Good luck,
Pete
___
PyQt mailing listPyQt@riverbankcomputing.com
http://www.riverbankcomputing.com/mailman/listinfo/pyqt