@anogayales:
Ja die Dokumentation von Qt suggeriert, dass das so funktionieren könnte, dem liegt aber ein entscheidender Denkfehler zugrunde. Bei genauerem Lesen der Dokumentation wird klar, das nur der Code unter run() einen eigenen Threadkontext erhält, d.h. das Threadobjekt selbst "lebt" dort, wo es erzeugt wurde - im Hauptthread. Das gilt für alle Deklarationen ausserhalb von run(). Deshalb blockiert Dein Buttonklick die GUI, die search-Methode wird im Hauptthread ausgeführt.
Der Code unter run() fungiert als main() des neuen Threads, von dort aus kannst Du weitere Objekte erstellen und auch einen eigenen Eventhandler anstossen. Dieser "interne" Eventhandler dient dann dazu, Events von Objekten, die innerhalb von run() erzeugt wurden, zu verwalten bzw. Signale von anderen Threads mit den eigenen threadinternen Events zu sychronisieren (siehe ConnectionType für Signal/Slot-Verbindungen).
Kleines Bsp., um den Threadkontext aufzuzeigen:
Code: Alles auswählen
from PyQt4 import QtGui, QtCore
class SubThread(QtCore.QThread):
def run(self):
print 'SubThread.run:', self.currentThread()
self.slotMethod()
print 'starte SubThread event loop..'
self.exec_()
print 'stoppe SubThread event loop..'
def slotMethod(self):
print 'SubThread.slotMethod:', self.currentThread()
class MyThread(QtCore.QThread):
def run(self):
print 'MyThread.run:', self.currentThread()
self.slotMethod()
self.subthread = SubThread()
self.subthread.start()
print 'starte MyThread event loop..'
self.exec_()
print 'stoppe MyThread event loop..'
def slotMethod(self):
print 'MyThread.slotMethod:', self.currentThread()
app = QtGui.QApplication([])
print 'Main thread:', app.instance().thread()
thread = MyThread()
thread.start()
QtCore.QTimer.singleShot(200, thread.slotMethod)
QtCore.QTimer.singleShot(200, thread.subthread.slotMethod)
QtCore.QTimer.singleShot(2200, app.quit)
QtCore.QTimer.singleShot(2100, thread.quit)
QtCore.QTimer.singleShot(2000, thread.subthread.quit)
app.exec_()
print "stoppe Main event loop.."
ergibt:
Code: Alles auswählen
Main thread: <PyQt4.QtCore.QThread object at 0x81ae5ac>
MyThread.run: <__main__.MyThread object at 0x81ae5ac>
MyThread.slotMethod: <__main__.MyThread object at 0x81ae5ac>
SubThread.run: <__main__.SubThread object at 0x81ae5ec>
SubThread.slotMethod: <__main__.SubThread object at 0x81ae5ec>
starte MyThread event loop..
starte SubThread event loop..
MyThread.slotMethod: <PyQt4.QtCore.QThread object at 0x81ae62c>
SubThread.slotMethod: <__main__.MyThread object at 0x81ae5ac>
stoppe SubThread event loop..
stoppe MyThread event loop..
stoppe Main event loop..
Hier siehst Du, das MyThread.slotMethod() einmal in MyThread (direkter Aufruf) und einmal im Hauptthread (Signal/Slot) auftaucht. Für den direkten Aufruf ist es klar, hier entscheidet der Caller-Kontext die Threadzugehörigkeit. Für die Signal/Slot-Sache ist es dagegen wichtig zu wissen, in welchem Thread das Objekt "lebt". So zeigt der Aufruf von SubThread.slotMethod via Signal vom Hauptthread auf den Kontext MyThread, da das Objekt SubThread hier erstellt wurde. Ohne Eventhandler in MyThread wird das Signal nicht mehr ausgeliefert und die Methode nicht mehr aufgerufen.
Zurück zu Deinem Problem, die search-Methode muß in irgendeiner Weise mit run() assoziiert sein, entweder durch direkten Aufruf oder durch ein dort erzeugtes Objekt mit der entsprechenden Methode. Einfacher gehts, wie lunar angedeutet hat.
