QAudioOutput vs QTimer strange behaviour
-
os: ubuntu 20.04
qt: 5.12.8the test is simple: https://github.com/a132791/TestQt3
the question is: then press on button two times - why is "HMMM" in console output ? -
@abarmotov said in QAudioOutput vs QTimer strange behaviour:
why is "HMMM" in console output ?
Because if (slotIsRunning_) is true.
-
@abarmotov said in QAudioOutput vs QTimer strange behaviour:
why is "HMMM" in console output ?
Because if (slotIsRunning_) is true.
@wrosecrans but how it set "true" ?
sorry - in first post the slotIsRunning_ is set to false in constructor
-
@abarmotov what are your other qDebug() telltales saying?
If there are no other places where slotIsRunning_ is set, the only way it can ever be true on slot entry is if your slot aborted before it got the chance to set slotIsRunning_ to false. That's why I'm curious whether you see the "QAudioOutput deleted" output.
EDIT:
Actually, what I posted above may not be quite true: if the slot gets invoked a second time before it's finished the first time, you'd see the output you're seeing. If this is undesirable behavior, you'll have to add logic to the function to prevent this.
-
@abarmotov what are your other qDebug() telltales saying?
If there are no other places where slotIsRunning_ is set, the only way it can ever be true on slot entry is if your slot aborted before it got the chance to set slotIsRunning_ to false. That's why I'm curious whether you see the "QAudioOutput deleted" output.
EDIT:
Actually, what I posted above may not be quite true: if the slot gets invoked a second time before it's finished the first time, you'd see the output you're seeing. If this is undesirable behavior, you'll have to add logic to the function to prevent this.
- if only one click done on button, then "QAudioOutput created" and "QAudioOutput deleted" printed and so on
- then done second click, then "HMMM" sometimes appears, for example "QAudioOutput created", "HMMM" "QAudioOutput created"
- on windows - never "HMMM" appears
is it possible and how this slot interrupted ?
is it possible to interrupt slot by other slot in "one thread - single event loop" app ?
there is no code other - only this "on_pushButton_clicked" -
- if only one click done on button, then "QAudioOutput created" and "QAudioOutput deleted" printed and so on
- then done second click, then "HMMM" sometimes appears, for example "QAudioOutput created", "HMMM" "QAudioOutput created"
- on windows - never "HMMM" appears
is it possible and how this slot interrupted ?
is it possible to interrupt slot by other slot in "one thread - single event loop" app ?
there is no code other - only this "on_pushButton_clicked"@abarmotov so here's your answer:
then done second click, then "HMMM" sometimes appears, for example "QAudioOutput created", "HMMM" "QAudioOutput created"
Your second click is coming before the first slot invocation has finished.
-
@mzimmers this project was made in creator - slot crated by "go to slot" command in designer, and it connected code by:
somewhere in Ui_MainWindow::setupUi ...QMetaObject::connectSlotsByName(MainWindow)@abarmotov I don't know a lot about this area, but evidently Creator is generating your connect statement for you. It looks to me like you want a queued connection, but you're not getting one. I want to point out that I very well could be mistaken about this; hopefully someone more knowledgable can jump in here.
As a total hack/band-aid, you could block your function by checking that variable and not proceeding until it's false:
void MainWindow::on_pushButton_clicked() { while (slotIsRunning_) { qDebug() << "HMMM"; // wait a few ms } ...
You'd probably want to put in a timer so that you don't wait forever if something goes wrong, but you could use this to test what's going on.
-
@abarmotov I don't know a lot about this area, but evidently Creator is generating your connect statement for you. It looks to me like you want a queued connection, but you're not getting one. I want to point out that I very well could be mistaken about this; hopefully someone more knowledgable can jump in here.
As a total hack/band-aid, you could block your function by checking that variable and not proceeding until it's false:
void MainWindow::on_pushButton_clicked() { while (slotIsRunning_) { qDebug() << "HMMM"; // wait a few ms } ...
You'd probably want to put in a timer so that you don't wait forever if something goes wrong, but you could use this to test what's going on.
@mzimmers i thought, that in singles thread qt app is not possible that slot interrupts another slot - they are serialized in execution
so maybe here bug with QAudioOutput somehow, because if i comments out "new QAudioOutput" - there is no "HMMM" in output
full source here: https://github.com/a132791/TestQt3
-
@mzimmers i thought, that in singles thread qt app is not possible that slot interrupts another slot - they are serialized in execution
so maybe here bug with QAudioOutput somehow, because if i comments out "new QAudioOutput" - there is no "HMMM" in output
full source here: https://github.com/a132791/TestQt3
@abarmotov evidently, you're right - calls to slots are queued and don't interrupt one another.
I'm running Qt 6.4 and made a couple changes to your slot. Program works as expected.
void MainWindow::on_pushButton_clicked() { if (slotIsRunning_) qDebug() << "HMMM"; slotIsRunning_ = true; // QAudioFormat format; QAudioOutput* audioPlayer_ = new QAudioOutput(); qDebug() << "QAudioOutput created"; QThread::sleep(1); // some work delete audioPlayer_; qDebug() << "QAudioOutput deleted"; slotIsRunning_ = false; QTimer::singleShot(std::rand()%50, this, &MainWindow::on_pushButton_clicked); }
The code wouldn't compile with the QAudioOutput c'tor as coded.
-
@wrosecrans but how it set "true" ?
sorry - in first post the slotIsRunning_ is set to false in constructor
@abarmotov said in QAudioOutput vs QTimer strange behaviour:
but how it set "true" ?
You set it to true in the slot, so I don't understand the problem.
On first slot call "HMMM" will not be printed but slotIsRunning_ will be set to true, so on second slot call you will print "HMMM"... -
@abarmotov evidently, you're right - calls to slots are queued and don't interrupt one another.
I'm running Qt 6.4 and made a couple changes to your slot. Program works as expected.
void MainWindow::on_pushButton_clicked() { if (slotIsRunning_) qDebug() << "HMMM"; slotIsRunning_ = true; // QAudioFormat format; QAudioOutput* audioPlayer_ = new QAudioOutput(); qDebug() << "QAudioOutput created"; QThread::sleep(1); // some work delete audioPlayer_; qDebug() << "QAudioOutput deleted"; slotIsRunning_ = false; QTimer::singleShot(std::rand()%50, this, &MainWindow::on_pushButton_clicked); }
The code wouldn't compile with the QAudioOutput c'tor as coded.
-
@abarmotov said in QAudioOutput vs QTimer strange behaviour:
but how it set "true" ?
You set it to true in the slot, so I don't understand the problem.
On first slot call "HMMM" will not be printed but slotIsRunning_ will be set to true, so on second slot call you will print "HMMM"... -
@mzimmers said in QAudioOutput vs QTimer strange behaviour:
I'm running Qt 6.4 and made a couple changes to your slot.
does it means what in 5.12 the QAudioOutput is broken ?
@abarmotov said in QAudioOutput vs QTimer strange behaviour:
does it means what in 5.12 the QAudioOutput is broken ?
Doubtful. According to the docs for 5.15, your constructor looks good (I notice you don't initialize your QAudioOutput object, but that shouldn't matter for this exercise).
I'm more suspecting there's something wrong with re-using your slot as the argument to the QTimer::singleShot call. When that's commented out, it seems to work fine, right?
-
@mzimmers said in QAudioOutput vs QTimer strange behaviour:
When that's commented out, it seems to work fine, right?
no, HMMM is still there on second click
but i tested only on 5.12.8@abarmotov Why do you think so? You wrote: "then press on button two times". So, as I explained: on the first button press you set slotIsRunning_ to true, so on second button press slotIsRunning_ is true and you print "HMMM". So, nothing is interrupted. Still don't get what the issue is...