Portál AbcLinuxu, 11. května 2024 20:46


Dotaz: PyQT4 a vlákna

19.1.2008 14:57 Jirka
PyQT4 a vlákna
Přečteno: 400×
Odpovědět | Admin
Dobrý den,

dělám programy, které spolu komunikují přes sockety (klient/server) a klienta jsem se rozhodnul udělat i v grafice. Tak jsem zkusil PyQT4, ale zasekl jsem se na jednom problému:

V programu musí pořád běžet jedno vlákno (nekonečný cyklus), které přijímá zprávy od serveru. A tyto zprávy pak potřebuji zobrazit v grafice, jenže tam mi to vždycky vyhodí error. Dám sem příklad, který jsem hodně ořezal:
from PyQt4 import QtCore, QtGui
import sys
import threading
import time
    
class oknoHlavni:

    def __init__(self):

        self.klient = klient(self)

        ##########################
        ## Hlavni okno programu ##
        ##########################
        
        self.app = QtGui.QApplication(sys.argv)
        self.mainWindow = QtGui.QMainWindow()
        self.mainWindow.setWindowTitle("Moje okno")
        self.mainWidget=QtGui.QWidget(self.mainWindow)
        self.mainWindow.setCentralWidget(self.mainWidget)
        self.layout=QtGui.QGridLayout(self.mainWidget)

        #################
        ## WIDGET CHAT ##
        #################

        self.widgetChat=QtGui.QWidget(self.mainWidget)
        self.layout.addWidget(self.widgetChat,1,0,1,1)
        
        self.layoutChat=QtGui.QGridLayout(self.widgetChat)

        # okno na zpravy - sklo
        self.chatSklo=QtGui.QTextEdit(self.widgetChat)
        self.chatSklo.setReadOnly(True)
        
        # prida objekty do layoutu
        self.layoutChat.addWidget(self.chatSklo,1,0,1,3)

        self.obnoveniOkna()
        self.klient.start()
        

    def obnoveniOkna(self):
        self.mainWindow.show()       
        

    def skloZapisText(self, text):
        print "skloZapisText: ", text
        self.chatSklo.setText(text)   

class klient:

    def __init__(self, rodic):
        self.grafika = rodic
    
    def start(self):
        v1 = threading.Thread(target = self.vlakno)
        v1.start()
    
    def vlakno(self):
        print "Vlakno"    
        for i in range(50):
            time.sleep(0.5)
            self.grafika.skloZapisText("Vlakno..."+str(i))
    
    
grafika = oknoHlavni()

sys.exit(grafika.app.exec_())
Program vypíše:
Vlakno

skloZapisText: Vlakno...0

QObject: Cannot create children for a parent that is in a different thread. Atd...
Předem díky za rady :-)
Nástroje: Začni sledovat (1) ?Zašle upozornění na váš email při vložení nového komentáře.

Odpovědi

okbob avatar 19.1.2008 20:30 okbob | skóre: 30 | blog: systemakuv_blog | Benešov
Rozbalit Rozbalit vše Re: PyQT4 a vlákna
Odpovědět | | Sbalit | Link | Blokovat | Admin
Zdar, neco podobneho jsem resil na .NETu. Jde o to, ze s GUI muze primo komunikovat pouze jeden thread. Na .NETu se to resi skrz jakousi proxy.
Luboš Doležel (Doli) avatar 20.1.2008 02:06 Luboš Doležel (Doli) | skóre: 98 | blog: Doliho blog | Kladensko
Rozbalit Rozbalit vše Re: PyQT4 a vlákna
Odpovědět | | Sbalit | Link | Blokovat | Admin
Dělat to takhle je fuj, od čeho jsou sloty/signály.
22.1.2008 21:19 Jirka
Rozbalit Rozbalit vše Re: PyQT4 a vlákna
A mohl bys mi, prosím, ukázat, jak to mám udělal přes ty sloty a signály? Signály a sloty umím použít třeba jen pro stisknutí tlačítka apod.

Zkusil jsem toto:

A do druhé třídy (klient) bych dal toto:

self.grafika(QtCore.SIGNAL("progress(int)"), nejake_cislo)

Do první třídy (oknoHlavni) bych dal toto:

self.app.connect(?co sem?, QtCore.SIGNAL("progress(int)"), self.skloZapisText)

Jenže co mám dát jako první parametr?
mess avatar 22.1.2008 21:51 mess | skóre: 43 | blog: bordel | Háj ve Slezsku - Smolkov
Rozbalit Rozbalit vše Re: PyQT4 a vlákna
Kdyby by ta třída klient dědila od QtCore.QObject, tak by se dal vyvolat vlastní signál přes self.emit. Více tady. A tady máš referenční příručku ke všem PyQt4 třídám.
Cez párne mesiace zošíváš vaginy, cez neparne montuješ hajzle.
Luboš Doležel (Doli) avatar 22.1.2008 22:00 Luboš Doležel (Doli) | skóre: 98 | blog: Doliho blog | Kladensko
Rozbalit Rozbalit vše Re: PyQT4 a vlákna
class klient : public QThread
{
Q_OBJECT
signals:
    void addText(QString text);
    // atd.
};

class oknoHlavni : public Q...
{
Q_OBJECT
slots:
    void textReceived(QString text);
};

// a pak někde
connect(m_pClient, SIGNAL(addText(QString)), this, SLOT(textReceived(QString)));

// posílání:
emit addText(nejakyText); // šlo mi snad i bez emit (?)
(Sorry, ale Python fakt ne-e.)
grubber avatar 22.1.2008 21:37 grubber | skóre: 6 | blog: grubber | Břeclav / Brno
Rozbalit Rozbalit vše Re: PyQT4 a vlákna
Odpovědět | | Sbalit | Link | Blokovat | Admin
Kdyz uz to pises s Qt, nebylo by lepsi pro vlakna pouzit QtCore.QThread misto threading.Thread? (strilim od boku, Qt znam jen z C++)
kozzi avatar 22.1.2008 22:01 kozzi | skóre: 55 | blog: vse_o_vsem | Pacman (Bratrušov)
Rozbalit Rozbalit vše Re: PyQT4 a vlákna
Bylo ale tomu nerikej :-D
Linux je jako mušketýři "jeden za všechny, všichni za jednoho"

Založit nové vláknoNahoru

Tiskni Sdílej: Linkuj Jaggni to Vybrali.sme.sk Google Del.icio.us Facebook

ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.