I have a child QDialog, when a button is pressed from it a socket is opened from QtConcurrent, and if there's an error an alert dialog is shown.
But if the user closes the child QDialog to return to the main window the signal cannot be received by the child QDialog slot.
I tried to broadcast the signal to parentWidget, but the program crashes, because this->parentWidget() doesn't exist anymore.
I use this code to emit the signal and connect it to the slot
connect(this, SIGNAL(errorTcpSignal(QString)), this, SLOT(displayTcpError(QString)));
connect(&t, QOverload<QAbstractSocket::SocketError>::of(&QAbstractSocket::error),[=](QAbstractSocket::SocketError err){
emit errorTcpSignal("Error while changing game settings \n" + QVariant::fromValue(err).toString());
});
Is there a way to solve this issue?
Thank you very much.
SOLVED:
emit the signal from the child widget, but set the connection from the father widget.
Related
In my Qt program, I have modal QDialogs that are meant to halt everything and not continue execution of code until after it is dismissed. And it works for the function it's in--I put a breakpoint on the next line of code after qDialog::exec() and it doesn't break until after I dismiss the dialog.
However, there is a QTimer connected to a slot on its timeout, and it will continue to go even when the modal dialog is up and execute the code in its slot.
I suppose I could stop the timer before showing the modal dialog. However, there may be cases when the dialog is in a totally different class than the timer. Is there a way to truly halt execution of the program until the QDialog is dismissed?
Example:
QTimer* pTestTimer = new QTimer( this );
connect( pTestTimer , SIGNAL( timeout() ), this, SLOT( timerSlot() ) );
//Slot code elsewhere
void cMyClass::deleteMeTimerSlot()
{
qDebug() << "See me during modal?";
}
//starting a modal dialog
pTestTimer->start( 1000 );
QDialog* pModalDlg = new QDialog( this, Qt::Dialog | Qt::FramelessWindowHint | Qt::WindowStaysOnTopHint );
pModalDlg->setModal(true);
pMOdalDlg->exec();
Output still shows "See me during modal?" while in exec();
I suppose I could stop the timer before showing the modal dialog.
However, there may be cases when the dialog is in a totally different
class than the timer.
Yes, you can do operate with all the timers accessible within the parent context (it seems like you look for generic solution).
// Halt all the timers within parent context.
// If all the timers have parent maybe the top app widget pointer
// should be used for parentObj
QList<QTimer*> listOfTimers = parentObj->findChildren<QTimer*>(
QString(), Qt::FindChildrenRecursively);
for(QTimer* pTimer : listOfTimers)
pTimer->stop();
Is there a way to truly halt execution of the program until the QDialog is dismissed?
Unless you mean stop all the threads: No, QDialog is part of the program and does not imply halting any execution but modal dialog runs in own event loop and only prevents user from operating the other program UI. I suppose you can probably restart all stopped timers after exiting the modal dialog.
pModalDlg->exec();
// restart all the timers within parent context
for(QTimer* pTimer : listOfTimers)
pTimer->start();
You can also peek at Qt source code (at QDialog and event loop it uses) and create your own sophisticated dialog class with very specific event loop for it.
I make a color picker based on Qt 5.4.1. It works as this: when user clicked one QToolButton, it shows the QColorDialog. I use the QToolButton's 'released()' signal. Now the problem is, when I close the QColorDialog, the released() signal fired again. But when I change it to QPushButton, the problem gone.
My toolbutton has no menu with it. I wonder if QToolButton is designed as this, or it's just a bug? Because other reason, I can't use QPushButton. So, is there some workround to make toolbutton work?
Update:
I tried put only the code below in the released slot:
static int n = 0;
qDebug() << Q_FUNC_INFO << ++n;
return;
the counter is increased 2 every click. So it should has nothing with the QColorDialog.
I finally find the reason. I've never noticed Qt has the ability to connect signals and slots automatically. That is, QMetaObject::connectSlotsByName(). I accidently give my slot a name like
void on_<object name>_<signal name>(<signal parameters>);
style, this is just the style what "QMetaObject::connectSlotsByName()" needed. So, Qt automatically connect the released() signal to my slot. And I manually connect them too. In Qt, connect a signal twice, it will fire twice, even the sender and receiver is the same!!!!
Simple Query:
If GUI widget window is hidden does it receives signals from other objects?
In our Qt application we have seen this issue/behaviour.
However, when window is shown it receives and process all the signals that it receives.
Every QObject (and hense every QWidget) receives signals until it's destroyed or the signal is disconnected. Visibility doesn't matter.
If you don't disconnect signals while hiding the QWidget they're received and processed.
I've made my first qt window. Now I'd like to make my first dialog, using qt. I have just finished creating the dialog, which is basically made of a QDialogButtonBox, and now I'd like to connect it to the window. I have two beginner's questions:
How can I retrieve how the dialog was closed (ok pressed or cancel pressed) from the window.cpp, which creates a new dialog, and then calls dialog->show() ?
Where and how to destroy the dialog pointer ?
If you use dialog->show() then I assume it's non-modal dialog.
If you have created QDialogButtonBox and connected its signals with accept() and reject() slots of your dialog as documentation shows, then your dialog will emit finished(int) and additionally accepted() or rejected() signals by which you can determine how it was closed.
If you need more customized behavior, then you can reimplement closeEvent(QCloseEvent *event) or create your own singnals.
If you need to delete your dialog you can use setAttribute(Qt::WA_DeleteOnClose, true);, which will delete instance on close.
you can use one flag, and signal and slot.
when put OK flag=1 , and when put cancel then flag=-1; and then use signal.
in in the window.h write code how to handle that flags with 1 simple slot.
for destroying the pointer you can use signal and slot in your Dialog and tell when user push
Ok, or Cancel , or exit (up- right (red cross)) go to slot in call the Destructer of dialog
and also you that you better set parent of dialog to window.
First Question:
When you want to show the dialog,just construct it,using myDialog *d = new myDialog(this)(the this pointer will make sure that you havn't to delete the pointer you created 'cause Qt will handle this if you specified the dialog's parent). And use d->exec() if you need a modal dialog, or d->show() to make it non-modal;
Second Question:
Once your specified the dialog's parent object, all u need is just use it and leave alone the memory managent,Qt will do this for you. Also you can use d->setAttribute(Qt::WA_DeleteOnClose,true) to make it destroy itself when it is closed.
Remember to link the QDialogButtonBox to your dialog's actions.
I create a QWidget in a plugin. I also use a QTimer so showing some data depends of time. When my QWidget is closed is must delete this QTimer but i can not because closeEvent is not called. What can be the problem ?
If by closed you mean destroyed, then you can connect the QWidget's destroyed() signal to the QTimer's destroy() slot.