Seite 1 von 2

QThread Problem

Verfasst: Sonntag 2. Januar 2011, 23:14
von waki
Hey,
hab das Problem, wenn ich diesen Thread starte, welcher immer BIlder empfängt und diese in einem neuen Dialog darstellen soll. Jedoch bekomm ich immer den Error: "QObject::killTimers: timers cannot be stopped from another thread"

Code: Alles auswählen

from PyQt4 import QtGui, QtCore, Qt
import socket, sys

class show_pics(QtCore.QThread):
    status = True
    #lock = QtCore.QReadWriteLock()
    
    
    def __init__(self):
        import tempfile
        self.screen = QtGui.QDialog()
        self.screen_view = QtGui.QGraphicsView(self.screen)
        self.screen.setWindowTitle(QtGui.QApplication.translate("Dialog", "Screen", None, QtGui.QApplication.UnicodeUTF8))
        self.scene = QtGui.QGraphicsScene(self.screen)
        server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        server.bind(("", 50001))
        server.listen(1)
        self.sock, self.ip = server.accept()
        QtCore.QThread.__init__(self)
        self.screen.show()
        self.screen_view.show()


    def run(self):
        while True:
            #if screen_cap.status == False:
            #    break
            size = int(self.sock.recv(1024))
            print size
            file = self.sock.recv(size)
            f = open("zwischen.jpg", "wb")
            f.write(file)
            f.close()
            pic = QtGui.QPixmap("zwischen.jpg")
            size = pic.rect()
            size = pic.rect()
            self.screen.resize(size.width(), size.height())
            self.screen_view.setGeometry(size)
            self.scene.clear()
            self.scene.addPixmap(pic)
            self.screen_view.setScene(self.scene)
        
 
            
            
   
            
app = QtGui.QApplication(sys.argv)     
g = show_pics()
g.start()
sys.exit(app.exec_())
Kann mir jemand sagen, was ich machen muss damit da alles rund läuft? ^^
Ach und nochmal ne Frage, ist es möglich dass Pixmap das Bild aus einem Tempfile laden kann? Wenn ich einfach QtGui.QPixmap(tmp), in der das Bild gespeichert war, genommen habe, gings nicht. Oder gibt es eine Möglichkeit das Empfangege direkt in eine Pixmap umzuwandeln?
Danke schonmal ;)

gruß

Re: QThread Problem

Verfasst: Montag 3. Januar 2011, 14:29
von JonasR
Hi,

ansich solltest du dein GUI von dem Hintergrundgewusel trennen. Heißt: Zwei Klassen eine für das GUI die andere startet den Server empfängt Daten etc. Desweiteren musst du dann mit Signalen und Slots arbeiten damit du sauber mit dem GUI arbeiten kannst.

Dazu mal ein Beispiel vom lunar welches mir geholfen hat Klick

Re: QThread Problem

Verfasst: Montag 3. Januar 2011, 18:09
von waki
Jo, ist klar. Nur bekomm ich dass mit den Signalen und Slots nicht ganz so auf die Reihe. Also das ganze clicked ist ja kein Problem, aber jetzt gerade bei meinem Beispiel. Ich wüsste nicht wie ich da die beiden Klassen verbinden könnte, außer über sehr umständliche Wege. Und bei dem Code-Snippet steig ich auch nicht ganz durch, wahrscheinlich weil ich ein ziemlicher Anfänger mit dieser GUI bin ^^ Würd mich über paar hilfreiche Links und Beispiele freuen ;)

Re: QThread Problem

Verfasst: Montag 3. Januar 2011, 19:22
von DaMutz
waki hat geschrieben:Würd mich über paar hilfreiche Links und Beispiele freuen ;)
Da hatte erst kürzlich jemand ein ähnliches Problem:
http://www.python-forum.de/viewtopic.ph ... 25#p188125
Hier wird eine Textdatei in einem separaten Thread zeilenweise ausgelesen und dann per Signal / Slot zeilenweise an die GUI gesendet und verarbeitet. Dein Vorhaben ist eigentlich das selbe, du liest Bilder von einer Netzwerkverbindung und musst sie dann an die GUI senden. Du kannst ja einmal mit Text starten und wenn dies geht auf Bilder wechseln...

Re: QThread Problem

Verfasst: Montag 3. Januar 2011, 19:32
von JonasR
Solltest aber aufpassen da ich in meinem Problem PySide und nicht PyQt4 benutze...
Es sollte reichen wenn du das

Code: Alles auswählen

from PySide import QtCore, QtGui
Durch

Code: Alles auswählen

from PyQt4 import QtCore, QtGui
ersetzt

Re: QThread Problem

Verfasst: Mittwoch 12. Januar 2011, 16:13
von waki
Noch eine Frage: GIbt es eine Möglichkeit diesen Teil ohne wzischenspeichern zu realisieren? also dass ich das Bild direkt in eine QPixmap umwandeln kann?

Code: Alles auswählen

f = open("zwischen.jpg", "wb")
f.write(file)
f.close()
pic = QtGui.QPixmap("zwischen.jpg")

Re: QThread Problem

Verfasst: Mittwoch 12. Januar 2011, 16:28
von lunar

Re: QThread Problem

Verfasst: Mittwoch 12. Januar 2011, 16:49
von waki
Thx
Ich hab jetzt eine anderes Problem, wenn ich "QtCore.Signal(unicode)" eingebe, dann sagt er mir, dass es Signal nicht gibt. Was mach ich falsch? ^^

Re: QThread Problem

Verfasst: Mittwoch 12. Januar 2011, 17:05
von lunar
Erwartest Du mit dieser Fehlerbeschreibung ernsthaft sinnvolle Antworten?!

Re: QThread Problem

Verfasst: Mittwoch 12. Januar 2011, 19:07
von waki
ok, hatte das mit Signal - Slot eingebaut - ausgeführt:

Code: Alles auswählen

    newPic = QtCore.Signal()
AttributeError: 'module' object has no attribute 'Signal'
€: Hab in der Dokumentation nachgeschaut: QtCore.pyqtSignal() hat dann geklappt. Jedoch empfängt meine GUI das Signal nicht. Hab so definiert:

Code: Alles auswählen

screen.newPic.connect(self.showe)
aber self.showe wird nicht ausgeführt...

Code: Alles auswählen

class View(QtGui.QDialog):
    
    
    def __init__(self):
        QtGui.QDialog.__init__(self)
        self.screen_view = QtGui.QGraphicsView(self)
        self.setWindowTitle(QtGui.QApplication.translate("Dialog", "Picture", None, QtGui.QApplication.UnicodeUTF8))
        self.scene = QtGui.QGraphicsScene(self)
        self.resize(1000, 800)
        
        screen.newPic.connect(self.showe)

    def showe(self):
        pic = QtGui.QPixmap("zwischen.jpg")
        size = pic.rect()
        self.resize(size.width(), size.height())
        self.screen_view.setGeometry(size)
        self.scene.clear()
        self.scene.addPixmap(pic)
        self.screen_view.setScene(self.scene)
        self.screen_view.show()
        
        


class model(QtCore.QThread):
    newPic = QtCore.pyqtSignal()

    
    def __init__(self):
        server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        server.bind(("", 50001))
        server.listen(1)
        self.sock, self.ip = server.accept()
        QtCore.QThread.__init__(self)
        
        

    def run(self):
        while True:
            size = int(self.sock.recv(1024))
            self.sock.send("ok")
            file = self.sock.recv(size)
            with open("zwischen.jpg", "wb") as f:
                f.write(file)
            f.close()
            self.newPic.emit()
g = model()
screen = View()
g.start()        
            
        

Re: QThread Problem

Verfasst: Mittwoch 12. Januar 2011, 20:16
von lunar
Und was soll diese Zeile bezwecken?!

Re: QThread Problem

Verfasst: Mittwoch 12. Januar 2011, 20:32
von waki
update oben....

Re: QThread Problem

Verfasst: Mittwoch 12. Januar 2011, 20:54
von lunar
Jetzt überlege mal, in welcher Klasse Du das Signal definiert hast, und welchen Typ das Objekt hat, bei dem Du versuchst, das Signal zu verbinden.

Re: QThread Problem

Verfasst: Mittwoch 12. Januar 2011, 21:29
von waki
weil sonst der QThread ein Problem meldet. Kann leider nicht den Fehlercode schicken, da ich am falschen pc bin...

Re: QThread Problem

Verfasst: Mittwoch 12. Januar 2011, 22:03
von lunar
Was immer Du mir damit sagen willst, mit meiner Anmerkung hat es jedenfalls nichts zu tun. Da Du diese also offenbar nicht verstanden hast, sage ich es Dir eben direkt: "screen.newPic.connect()" funktioniert deswegen nicht, weil "screen" gar kein "newPic"-Attribut hat. "screen" ist nämlich vom Typ "View", das "newPic"-Signal aber wird in der Klasse "model" definiert. Und wo kein Signal existiert, kann man natürlich auch keins verbinden.

Generell solltest Du beim Programmieren ein bisschen mehr Sorgfalt walten lassen und ein bisschen struktierter vorgehen, dann geschehen solche einfachen Fehler erst gar nicht.

Re: QThread Problem

Verfasst: Donnerstag 13. Januar 2011, 13:31
von waki
Jetzt weiß ich was du meinst. Das ist nur ein Fehler hier, sry, habe es eigentlich so geschrieben:

Code: Alles auswählen

g = View()
screen = model()
screen.start() 
Und es funktioniert so nicht ^^

Re: QThread Problem

Verfasst: Donnerstag 13. Januar 2011, 13:42
von Hyperion
Was hat das mit lunars Hinweisen zu tun? Das ändert nichts an dem beschriebenen Problem.

Re: QThread Problem

Verfasst: Donnerstag 13. Januar 2011, 13:43
von waki
Dass sich das Signal newPic sehrwohl im Object screen ist...

Re: QThread Problem

Verfasst: Donnerstag 13. Januar 2011, 13:48
von Hyperion
waki hat geschrieben:Dass sich das Signal newPic sehrwohl im Object screen ist...
Du meintest "befindet"?

Du hast drei Zeilen gezeigt, in denen Du Instanzen von Klassen bildest und Methoden aufrufst. Daraus kann ich nicht sehen, was Du ggf. an der Klasse View intern geändert hast!

Re: QThread Problem

Verfasst: Donnerstag 13. Januar 2011, 13:54
von waki
Davor war "screen" eine Instanz der View-Klasse. Dies war jedoch nur ein Fehler hier, in meinem code ist "screen" die model-Klasse. Und in der Model-Klasse befindet sich das Signal newPic. Und dieses soll mit screen.newPic.connect() mit der View-Klasse verbunden werden, jedoch funktioniert dies nicht, da danch nicht die gewünschte Funktion beim auslösen des Signals aufgerufen wird...