Seite 1 von 1

Trhead sendet signal nicht zum Mainwindow

Verfasst: 23. März 2011 08:42
von geostein8888
Hallo,
ich habe ein programm, inwelchem ich einen Thread starte, welche in einer schleife im Hauptfenster ein Bild austauschen soll.

MainWindow Threads starten:

Code: Alles auswählen

    //start the ChannelListAdsChanger
    channelBarAd = new AdsChanger(this,this->msmAdsManager,this->datahandler,this->properties);

    channelBarAd->start();

    QObject::connect(this->channelBarAd, SIGNAL(sigChangeAdd()), this, SLOT(slotChangeAdChannelBar()));
MainWindow Slot:

Code: Alles auswählen

void slotChangeAdChannelBar();//QPixmap *pix
Main Slot implementierung:

Code: Alles auswählen

 void MainWindow::slotChangeAdChannelBar(){//QPixmap *pix
    qDebug() << "+++++++++++++++++++++++ imageLoaded: ";// << pix->height();
     //this->ui->lblChannelAd->setPixmap(*pix);
 }
Thread run:

Code: Alles auswählen

void AdsChanger::run(){
    QString adsPath = properties->getAdsPath();

    int actRuns = 0;

qDebug() << "AdsChanger: started";
    while(!this->stopped && (this->adsRepeats == -1 || actRuns <= this->adsRepeats)){
        //change ads
        QPixmap *pix = this->msmAdsManager->getNextAdsPicture(this->adsType,this->adsChannel,this->adsFormat);

        //send signal back to the calling function
        emit this->sigChangeAdd();//pix


        this->wait(this->adsInterval);
        actRuns++;
    }
   this->stopped = false;
}
Signal im Thread:

Code: Alles auswählen

signals:
    void sigChangeAdd();//QPixmap *pix
Das Programm macht alles wie es soll, liest das Bild mit einer weiteren Klasse ein kommt zum emit, nur der Slot wird nie ausgeführt.

Habe ich hier irgendwas wichtiges vergessen?

Georg

Verfasst: 23. März 2011 09:10
von franzf
Hast du überall brav Q_OBJECT in der Klassendefinition stehen? (MainWin + Thread)
Ansonsten ladss bitte das dauernde "this->" weg. Das ist in C++ (im Gegensatz zu Java) nämlich NICHT notwendig und erzeugt nur unnötiges Rauschen. Außerdem brauchst du definitiv keinen eigenen Thread, um ein Bild zu laden. Du gibst hier zusätzlich einen pointer an dem Thread und greifst ungeschützt darauf zu (oder hast du in den entsprechenden Klassen Mutexe am arbeiten?)

Verfasst: 23. März 2011 09:30
von geostein8888
ja das Q_OBJECT hab ich da über all, war so das 2. was ich geprft hatte.
welche pointer genau meinst du denn, das ganze ist noch nicht feritg, da ich ja am anfang schoin gescheitert bin.
den Thread mache ich , da das ganze im Hintergrund laufen soll und so eine art AdRotation wird welche aber nur getsartet wird, wenn der Bildbereich nicht gerade anderwertig benutzt wird.

Georg

Verfasst: 23. März 2011 09:49
von franzf
geostein8888 hat geschrieben:welche pointer genau meinst du denn, das ganze ist noch nicht feritg, da ich ja am anfang schoin gescheitert bin.
Alle Pointer, die du dem Konstruktor deines Threads übergibst. Die leben im MainThread, wenn du auf Methoden aus einem anderen Thread zugreifst, musst du das Objekt per Mutex schützen.
Was garantiert als nächstes schiefgeht, sollte die Signal/Slot-connection mal funktionieren, ist die Übergabe des Pixmap: Du kannst ein QPixmap nicht in einem anderen Thread erzeugen, wenn du das im MainThread verwenden willst. QImage würde gehen.
den Thread mache ich , da das ganze im Hintergrund laufen soll und so eine art AdRotation wird welche aber nur getsartet wird, wenn der Bildbereich nicht gerade anderwertig benutzt wird.
Das ist trotzdem total wurscht. Ein pixmap ist sofort geladen, da merkst du keine Verzögerung in der GUI. Wenn die Werbung aus dem Internet geladen werden soll ist das auch kein Problem, Internetkommunikation läuft schon asynchron, es wird also nicht blockiert.

Du scheinst mit THreads noch nicht so wirklich in Berührung gekommen zu sein. Lies dich dazu erstmal schlau, das Thema ist verdammt verzackt, und auch wenn es Qt einfacher macht, kannst du noch viel (zu viel) falsch machen.

Verfasst: 23. März 2011 10:09
von geostein8888
Hallo,
das mit den Threads muss ich mir wie du schn sagtest noch genauer ansehen, ich bin vor 4 Wochen noch Java Programmierer gewesen, hatte aber vor etwa 10 Jahren MFC programmiert ist also schon en weile her.

Ich war der Meinung am besten mache ich das mit einem Thread, der dann alle 5 Minuten das Bild austauscht nur wie gesagt, wird das signal das dann im MainWindow selbiges tun soll nie im Thread gesendet.

Kann man diese Signale im QT Creator irgendwie debuggen, hab da bisher nix gefunden?

Georg

Verfasst: 23. März 2011 10:33
von franzf
Tjo, da hätte ich sogar richtig vermutet, wollte aber selber erst testen:
Es liegt am wait()!
Bitte starte IMMER deine Programme in einer Konsole, damit du mitbekommst, was dir dein Programm zu sagen hat:

Code: Alles auswählen

f
QThread::wait: Thread tried to wait on itself
QThread::wait: Thread tried to wait on itself
QThread::wait: Thread tried to wait on itself
QThread::wait: Thread tried to wait on itself
QThread::wait: Thread tried to wait on itself
QThread::wait: Thread tried to wait on itself
QThread::wait: Thread tried to wait on itself
QThread::wait: Thread tried to wait on itself
usw.
Du bekommst ein eiziges Signal (das vor dem ersten wait), das fängst aber nie, da du den Thread VOR dem connect startest.
Ansonsten:
* schau dir an was wait() wirklich macht
* ersetze wait durch sleep
* schau was sleep macht
* Lass den Thread bleiben, und verwende stattdessen in der GUi einen QTimer.

Verfasst: 23. März 2011 16:40
von brax
franzf hat geschrieben:Ansonsten ladss bitte das dauernde "this->" weg. Das ist in C++ (im Gegensatz zu Java) nämlich NICHT notwendig und erzeugt nur unnötiges Rauschen.
OT:
Das ist auch in Java nicht notwendig.

Über das "Rauschen" kann man geteilter Meinung sein, ist IMO eher eine Stylefrage. Manch einer mag es, um zu verdeutlichen, dass auf Membern des Objekts gearbeitet wird. Ich hatte sogar mal einen Arbeitgeber, bei dem die explizite Verwendung von this im Styleguide stand (in dem Fall sowohl für C# als auch C++).

Einen Vorteil, den ich sehe, ist, dass damit die Vorschläge von Intellisense und co. schneller kommen, so dass ich es wenn ich mich in ein neues größeres Projekt einarbeiten muss auch gelegentlich benutze um zu sehen, welche Möglichkeiten, ich überhaupt habe.

Sorry, wollte ich nur einwerfen, weil in letzter Zeit immer mehr seltsame Hinweise auf Java kommen, die nicht so ganz richtig sind... ;)

Verfasst: 23. März 2011 18:43
von franzf
brax hat geschrieben:OT:
Das ist auch in Java nicht notwendig.
Aha, danke. Mir wurde in meiner Java-Zeit immer gesagt "mach, das muss sein, geht nicht anders". Ist das evtl. ein neueres Feature?
Über das "Rauschen" kann man geteilter Meinung sein, ist IMO eher eine Stylefrage. Manch einer mag es, um zu verdeutlichen, dass auf Membern des Objekts gearbeitet wird. Ich hatte sogar mal einen Arbeitgeber, bei dem die explizite Verwendung von this im Styleguide stand (in dem Fall sowohl für C# als auch C++).
Man sieht durch das "this" sofort, dass es sich um einen Zugriff auf einen Member handelt. Will man aber eine längere Code-Passage verstehen oder debuggen, und hat immer und überall die this, verdeckt einem (sprich: mir :D) die Sicht auf das Wesentliche.

Code: Alles auswählen

this->that->doSomethingMore( this->memberA, this->prepareSomethingLess(), this->buffer );

Code: Alles auswählen

that->doSomethingMore( memberA, prepareSomethingLess(), buffer );
Einen Vorteil, den ich sehe, ist, dass damit die Vorschläge von Intellisense und co. schneller kommen, so dass ich es wenn ich mich in ein neues größeres Projekt einarbeiten muss auch gelegentlich benutze um zu sehen, welche Möglichkeiten, ich überhaupt habe.
Dann ist IntelliSense aber nicht wirklich intelligent. Der sollte erkennen, dass man gerade im Scope einer Klasse ist, und entsprechend die Vervollständigungsliste sortieren.
KDevelop macht das :P
Cursor in eine Zeile einer Funktion setzen, Strg+Leertaste und es wird alles sortiert angezeigt:
* Local
* Public
* Protected
* Private
* Namespaces, absteigend. (anonymer ns, ns der Klasse, weiter rauf bis globaler ns, dann der ganze Rest)
Sorry, wollte ich nur einwerfen, weil in letzter Zeit immer mehr seltsame Hinweise auf Java kommen, die nicht so ganz richtig sind... ;)
Passt schon, kein Problem, immer gerne, man will ja nicht dumm und unwissend sterben :P

// edit:
Ich will nicht widersprechen, jeder hat seine Vorlieben. Ich spreche nur aus der Sicht eines "this->"Geschädigten.
Und wenn man sich in der OSS-Welt umschaut, findet man auch so gut wie nie ein konsequent durchgezogenes "this->"-Feuerwerk.

Verfasst: 23. März 2011 18:53
von brax
franzf hat geschrieben: Aha, danke. Mir wurde in meiner Java-Zeit immer gesagt "mach, das muss sein, geht nicht anders". Ist das evtl. ein neueres Feature?
Ich weiß nicht wann Du Java programmiert hast. In Java 2 (1998 - mein Erstkontakt) ging das jedenfalls schon.

Code: Alles auswählen

this->that->doSomethingMore( this->memberA, this->prepareSomethingLess(), this->buffer );
Da hast Du natürlich recht.
Dann ist IntelliSense aber nicht wirklich intelligent. Der sollte erkennen, dass man gerade im Scope einer Klasse ist, und entsprechend die Vervollständigungsliste sortieren.
Das Intellisense nicht wirklich intelligent ist stimmt ;)
Aber Du hast recht, das funktioniert natürlich auch.

An geostein: Nochmal entschuldigung für den OT Exkurs