Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » KDevelop / Qt / wxWidget » QT Thread Problem

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
06.05.2007, 02:26 Uhr
~arkadius
Gast


Hi,

ich habe ( mal wieder ) ein Problem wo ich gar nicht weiter komme und im Netz irgendwie nix finde. Mal folgendes kleiner Programm


C++:
class MyWindow : public QMainWindow, public QThread{
    
    public:
        MyWindow()
        :infoWidget(new QWidget()),connections(new QLabel()){
            initLayout();
            connections->setText("Empty");
            setCentralWidget(infoWidget);        
            QThread::start();
        }
    protected:
        void run(void){
            for(int i = 0; i < 100; i++){
                std::stringstream stream;
                stream<<"connections : "<<i;
                std::cout<<stream.str()<<std::endl;
                connections->setText(stream.str().c_str());
                
            }
        }
        void initLayout(void){
            BorderLayout *layout = new BorderLayout;
            layout->addWidget(connections,BorderLayout::East);
            infoWidget->setLayout(layout);
        }
    private:
        QWidget *infoWidget;
        QLabel  *connections;
};



Ich möchte in der Methode run() ( die ein einem Thread laufen soll ) den Text vom QLabel connections ändern, was aber überhaupt nicht will, ich bekomme als Meldung


Zitat:

QObject: Cannot create children for a parent that is in a different thread.



Kurz und knapp : Hilfe !!!!
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
06.05.2007, 19:41 Uhr
stephanw
localhorst


Meine Antwort bezieht sich auf Qt4... was benutzt Du ?

In Qt ist jedes QObject einem Thread zugeordnet. Laut der Fehlermeldung können Eltern- und Kindobjekte nicht verschiedenen Threads angehören (z.B. der Parent-Widget und Child-Widget).

Normalerweise ist ein QObject dem Thread zugeordnet, in dem es erzeugt wurde. Man kann aber auch explizit einen Thread angeben, zu dem es ab dann gehören soll (siehe Dok. für QObject). Wo jetzt aber in Deinem Code-Beispiel Widgets eine Eltern-Kind-Beziehung eingehen, die in versch. Threads leben, sehe ich grad nicht. In welchem Thread "MyMainWindow" lebt (das ja selbst ein Thread ist), weiß ich auch nicht aus dem Hut. Aber vielleicht hilft Dir das bei der Fehlersuche oder auf der Suche nach den richtigen Seiten in der Dokumentation
--
Reden ist Schweigen und Silber ist Gold.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
06.05.2007, 23:25 Uhr
Blubber2063



Na also spontan gesagt, würde ich mal behaupten das alle Widgets, die nicht extra einem anderen Thread zugeordnet sind, im Main Thread laufen. Ich verstehe hier nicht warum du das Widget von einem Thread ableitest, das ist unnötig, da du ja mit jedem MyWindow Widget einen neuen Thread anlegst. Wenn du beim Start vom Main Thread losgekopplet was machen willst, dann erzeuge dir doch dort einen neuen Thread, ansonsten legt doch deine Klassenableitung nahe dass das Fenster in einem eigenen Thread laufen soll(aber es läuft ja eigentlich im MainThread, wo die Message Loop auch stattfindet, also warum für die Anzeige ein extra Thread).
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
07.05.2007, 14:34 Uhr
~arkadius
Gast


Hi,

das obige Beispiel ist nun ( ehrlich gesagt ) mehr als sinnlos. Mir ist die Fehlermeldung schon klar, ich will nun das es geht. Mal so grob was ich eigentlich will.

Ich habe ein Server Programm laufen. Ich will nun eine GUI haben, die mir die Anzahl der Verbindungen auf dem Server anzeigt usw. usw. usw.

In der GUI habe ich QLabels mit Bezeichnungen wie

- Anzahl Verbindungen
- Belegter Speicher
- usw. usw.

Ich muss mir nun immer die Daten vom Server holen, also ein Thread ( damit die GUI nicht blockiert ) und diese Funktion heisst run ( oder wie auch immer ). Ich hole mir die Daten nun, und will diese nun in der GUI anzeigen in den Labels.

also


Code:
void run(void){
       // Hole Daten vom Server und setze setze nun die Daten in die QLabels
}



Wie kann ich nun aus dem Thread heraus, den Text von einem QLabel ( der im MainThread ) vorhanden ist ändern ?
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
07.05.2007, 17:26 Uhr
Blubber2063



Ich denke das machst du am schlausten in dem du einen extra Thread aufmachst, aber nur nen Thread nicht ne Ableitung von den Widgets, der Thread wird bestandteil deines MainWin und sendet dann die Daten per Signal, die das MainWin mit seinen Slots dann weiterverarbeitet.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
09.05.2007, 08:57 Uhr
stephanw
localhorst


Ja, so wäre das sinnvoll. Wenn Du Qt4 verwendest, kannst Du auch zwischen verschiedenen Threads mit Signal-Slot Nachrichten verschicken - Qt entkoppelt das automatisch, indem es die "Verbindung" über Events nachbildet statt über direkte Funktionsaufrufe.
Im Prinzip also so hier:


C++:

class ServerInfoThread : public QThread
{
  Q_OBJECT
  ...
signals:
  void signalNumConnections(int);
};


class MainWindow : public QMainWindow
{
  Q_OBJECT
  ...
public slots:
  void slotNumConnections(int nc) {
    connections_.setText( QString::number(nc) );
  }

private:
  QLabel* connections_;
  ServerInfoThread* thread;
};




Nutzt Du Qt3, müsstest Du statt signal-slot Events verwenden, also ein spezielles Event aus dem Thread ans MainWindow schicken (mit postEvent()) und dann dort abfangen. Ist aber nicht so dramatisch.
--
Reden ist Schweigen und Silber ist Gold.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
09.05.2007, 15:25 Uhr
stephanw
localhorst


Als Ergänzung:

Falls Du das mit Signal-Slot machst, könntest Du auch das Signal des Threads direkt mit einem passenden Slot des Labels verbinden (oder ggf. ein angepasstes Label verwenden). Dann muss das MainWindow nur noch die Verbindung darstellen, was imho sauberer wäre.
--
Reden ist Schweigen und Silber ist Gold.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ KDevelop / Qt / wxWidget ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: