QT Event Verständnissproblem
QT Event Verständnissproblem
Hallo Community,
Ich habe zur Zeit ein Problem mit den Events von QT. Und zwar habe ich ein Mainwindow und möchte gerne per Event überprüfen ob einer mit der Maus über einem Button ist. Dies geht so wie ich mitbekommen habe mit den Event enter und leave von der Klasse QPushbutton. Wie bekomme ich es hin das ich auf diese Events zugreifen kann, wenn ich ein Mainwindow habe. Das Problem ist hierbei das ich nicht auf die Events von dem Mainwindow drauf zugreifen möchte sondern auf die von QPushbutton.
Ich habe zur Zeit ein Problem mit den Events von QT. Und zwar habe ich ein Mainwindow und möchte gerne per Event überprüfen ob einer mit der Maus über einem Button ist. Dies geht so wie ich mitbekommen habe mit den Event enter und leave von der Klasse QPushbutton. Wie bekomme ich es hin das ich auf diese Events zugreifen kann, wenn ich ein Mainwindow habe. Das Problem ist hierbei das ich nicht auf die Events von dem Mainwindow drauf zugreifen möchte sondern auf die von QPushbutton.
habe jetzt ein neues problem das damit zusammenhängt. Und zwar funktioniert alles super wenn ich es auf debug lasse. Sobald ich aber auf release umstelle zeigt er mir die button bei denen ich installEventFilter ausführe nicht mehr an. Sie sind zwar noch da, da die leave und Enter events noch funktioneren aber sie werden komplett nicht mehr angezeigt. Keine Schrift und kein Button
Code: Alles auswählen
bool MainWindow::eventFilter(QObject *obj, QEvent *event)
{
if (obj == ui->qpbAccept || obj == ui->qpbNext || obj == ui->qpbPreview || obj == ui->qpbUp)
{
if (event->type() == QEvent::Leave)
{
mediaObject->pause();
qDebug()<<"mediaObject "<<mediaObject->state();
return false;
}
if (event->type() == QEvent::Enter)
{
Mp3Data= QString(QDir::homePath() +"/Klickloesung/Soundfiles/");
if(obj == ui->qpbAccept)
{
if(mediaObject->state() == Phonon::PlayingState)
{
Mp3Data.append("Pause.mp3");
}else
{
Mp3Data.append("Accept.mp3");
}
}
if(obj == ui->qpbNext) Mp3Data.append("Next.mp3");
if(obj == ui->qpbPreview) Mp3Data.append("Preview.mp3");
if(obj == ui->qpbUp) Mp3Data.append("Up.mp3");
Musik();
return true;
}
}
}
Er ruft für jeden Button eine Mp3 Datei auf.
Musik() ist meine phonon Methode die alles Abspielt
in meinem Mainwindow Konstruktor
Code: Alles auswählen
ui->qpbAccept->installEventFilter(this);
ui->qpbNext->installEventFilter(this);
ui->qpbUp->installEventFilter(this);
ui->qpbPreview->installEventFilter(this);
-
chrislo1976
- Beiträge: 105
- Registriert: 24. Februar 2008 09:45
Moin!
Wenn ich mich nicht irre kommt hier der Stack durcheinander! Aber das können die Profis hier bestimmt besser, genauer erklären.
Ich habe mir angewohnt am Ende einer Funktion IMMER einer Return zu haben...
Gruß,
Christian
DAS würde ich aber nicht sagen! Hatte deswegen schon mal riesige Probleme!ist aber egal. Auch wenn man als rückgabedatentyp bool hat und keinen rückgabedatentyp zurückgibt ist das nicht so schlimm es zeugt nur von schlechtem Programmierstil
Wenn ich mich nicht irre kommt hier der Stack durcheinander! Aber das können die Profis hier bestimmt besser, genauer erklären.
Ich habe mir angewohnt am Ende einer Funktion IMMER einer Return zu haben...
Gruß,
Christian
-
Christian81
- Beiträge: 7319
- Registriert: 26. August 2004 14:11
- Wohnort: Bremen
- Kontaktdaten:
http://stackoverflow.com/questions/2934 ... value-in-c
Die Aussage ist klar, sogar mit Zitat des Standard: Undefined Behaviour.
Aber auch wenn es "nur" schlter Stil wäre, ist das hier ein Problem: Es wird von eventFilter ein definitives Statement erwartet, ob das Eventhandling nach dem filter abgebrochen werden soll oder nicht. Und wenn jetzt zufällig ein "true" zurückgegeben wird, sitzt du im Trockenen bei allen events - auch beim PaintEvent. Deshalb: return false (oder besser return <ParentClas>::eventFilter(object, event); falls die parent-klasse schon nen eventFilter implementiert) am Ende des eventFilter, und ich denke der Button wird wieder sichtbar
edit @Christian:
undefined behaviour ist noch viel schlimmer als etwas undefiniertes zurückgeben. Es kann die Festplatte formatieren, den Rechner implodieren lassen, die Milch in der Küche zum Überlaufen bringen - das Universum zerstören
Deshalb immer dann, wenn der Standard sagt "undefined behaviour" auch immer garantiert die Finger davon lassen!
Die Aussage ist klar, sogar mit Zitat des Standard: Undefined Behaviour.
Aber auch wenn es "nur" schlter Stil wäre, ist das hier ein Problem: Es wird von eventFilter ein definitives Statement erwartet, ob das Eventhandling nach dem filter abgebrochen werden soll oder nicht. Und wenn jetzt zufällig ein "true" zurückgegeben wird, sitzt du im Trockenen bei allen events - auch beim PaintEvent. Deshalb: return false (oder besser return <ParentClas>::eventFilter(object, event); falls die parent-klasse schon nen eventFilter implementiert) am Ende des eventFilter, und ich denke der Button wird wieder sichtbar
edit @Christian:
undefined behaviour ist noch viel schlimmer als etwas undefiniertes zurückgeben. Es kann die Festplatte formatieren, den Rechner implodieren lassen, die Milch in der Küche zum Überlaufen bringen - das Universum zerstören
oh man vielen Dank. Das war das problem ich hab return weggelassen und um zu testen ob es an dem return liegt habe ich return true; gemacht ^^.
Oh man ich glaub da wäre ich in 100 Jahren nicht drauf gekommen. Jetzt funktionert es.
Habe aber denoch eine weitere Frage zum Thema Phonon. Ich möchte eine Mp3 Datei laufen lassen und eine Weitere Mp3 Datei soll abspielbar sein.
Deshalb habe ich mir gedacht initialisiere ich das eine MediaObjekt in meiner "Normalen" Klasse und das andere in einem Thread.
Was soll funktionieren:
Mp3 File wird abgespielt (funktioniert)
wenn über einen Button gegangen wird soll 1. Mp3 File (0,5sec) Pause machen. (Funktionert nicht)
Dann soll nach den 0,5sec das 2.Mp3 File abgespielt werden. Wenn dies fertig ist soll noch 0,5sec gewartet werden und das 1. Mp3 file weiter laufen.
Normaler weise müsste man das 1. Mp3 File ja mit pause stoppen können und später wieder aufrufen können. dies Funktionert bei mir aber nicht. Den sobald ich das 1.Mp3 file Pausiere und das 2. Mp3File aufrufe kann ich das 1. nicht mehr weiter laufen lassen.
QThread
Mainwindow
// mt = new MyThread;
Oh man ich glaub da wäre ich in 100 Jahren nicht drauf gekommen. Jetzt funktionert es.
Habe aber denoch eine weitere Frage zum Thema Phonon. Ich möchte eine Mp3 Datei laufen lassen und eine Weitere Mp3 Datei soll abspielbar sein.
Deshalb habe ich mir gedacht initialisiere ich das eine MediaObjekt in meiner "Normalen" Klasse und das andere in einem Thread.
Was soll funktionieren:
Mp3 File wird abgespielt (funktioniert)
wenn über einen Button gegangen wird soll 1. Mp3 File (0,5sec) Pause machen. (Funktionert nicht)
Dann soll nach den 0,5sec das 2.Mp3 File abgespielt werden. Wenn dies fertig ist soll noch 0,5sec gewartet werden und das 1. Mp3 file weiter laufen.
Normaler weise müsste man das 1. Mp3 File ja mit pause stoppen können und später wieder aufrufen können. dies Funktionert bei mir aber nicht. Den sobald ich das 1.Mp3 file Pausiere und das 2. Mp3File aufrufe kann ich das 1. nicht mehr weiter laufen lassen.
QThread
Code: Alles auswählen
#include "mythread.h"
MyThread::MyThread()
{
audioOutput2 = new Phonon::AudioOutput(Phonon::MusicCategory, this);
mediaObject2 = new Phonon::MediaObject(this);
metaInformationResolver2 = new Phonon::MediaObject(this);
mediaObject2->setTickInterval(1000);
}
void MyThread::run(QString Mp3Data)
{
Phonon::createPath(mediaObject2, audioOutput2);
if(mediaObject2->state() == Phonon::PlayingState)
{
mediaObject2->pause();
}
qDebug()<<"Mp3Data "<<Mp3Data;
int index = sources2.size();
Phonon::MediaSource source(Mp3Data);
sources2.append(source);
metaInformationResolver2->setCurrentSource(sources2.at(index));
mediaObject2->setCurrentSource(metaInformationResolver2->currentSource());
mediaObject2->play();
exec();
}
// mt = new MyThread;
Code: Alles auswählen
bool MainWindow::eventFilter(QObject *obj, QEvent *event)
{
if (obj == ui->qpbAccept || obj == ui->qpbNext || obj == ui->qpbPreview || obj == ui->qpbUp)
{
if (event->type() == QEvent::Leave)
{
eventdown = true;
if(mt->mediaObject2->state() == Phonon::PlayingState)
{
mt->mediaObject2->pause();
}
}
if (event->type() == QEvent::Enter && eventdown)
{
eventdown = false;
Mp3Data= QString(QDir::homePath() +"/Klickloesung/Soundfiles/");
if(obj == ui->qpbAccept)
{
Mp3Data.append("Accept.mp3");
}
if(obj == ui->qpbNext) Mp3Data.append("Next.mp3");
if(obj == ui->qpbPreview) Mp3Data.append("Preview.mp3");
if(obj == ui->qpbUp) Mp3Data.append("Up.mp3");
mt->run(Mp3Data);
}
}
return false;
}
Also, bevor du dich an eine gethreadete Audioausgabe machst (deren Sinn eventuell noch zu prüfen ist), solltest du dich eventuell mal mit der Doku und/oder Grundlagen zur Threadprogrammierung beschäftigten.
Dann kommst du unweigerlich an so Sachen wie Synchronisierung, konkurrierender Zugriff etc. pp vorbei, und findest die Fehler in deinem geposteten Code
Wenigstens in der Qt Doku gibt es gute und einfache Beispielem die Zeigen, wie Threads zu benutzen sind.
Dann kommst du unweigerlich an so Sachen wie Synchronisierung, konkurrierender Zugriff etc. pp vorbei, und findest die Fehler in deinem geposteten Code