QMessageBox::question relative to parent...
-
My main window appears in the center of the desktop, when I display a question message box, I have the following code:
clsMainWnd* pobjMainWnd(clsMainWnd::pobjGetAppWnd()); return (QMessageBox::question(pobjMainWnd, crstrTitle, crstrQuestion) == QMessageBox::StandardButton::Yes);
The message box is displayed but does not appear centered in the parent window, instead it appears offset to the left of the parent window.
I also tried:
QMessageBox msgBox; msgBox.setWindowTitle(crstrTitle); msgBox.setText(crstrQuestion); msgBox.setStandardButtons(QMessageBox::Yes); msgBox.addButton(QMessageBox::No); msgBox.setDefaultButton(QMessageBox::No); QRect rctMsg(msgBox.geometry()); rctMsg.moveCenter(clsMainWnd::rctDesktop().center()); msgBox.setGeometry(rctMsg); return (msgBox.exec() == QMessageBox::Yes);
That doesn't work either, the end result is the message dialog appears top left of the parent.
Is there something wrong with my code? I'm using Qt 5.15.2 clang 64bit on macOS Monterey version 12.7.1
Also, I'm not sure if this is a bug, but the window title is not appearing, I've checked the prototype and I am supplying a value in crstrTitle which is passed in as const QString& crstrTitle, it has content but is not bring displayed. This is the same for both attempts, no title appears.
-
@mpergand , thank you for the response, what I posted is exactly the code I am using.
This is the full function:
bool clsScriptHelper::askYesNo(const QString& crstrTitle ,const QString& crstrQuestion) { QMessageBox msgBox; msgBox.setWindowTitle(crstrTitle); msgBox.setText(crstrQuestion); msgBox.setStandardButtons(QMessageBox::Yes); msgBox.addButton(QMessageBox::No); msgBox.setDefaultButton(QMessageBox::No); QRect rctMsg(msgBox.geometry()); rctMsg.moveCenter(clsMainWnd::rctDesktop().center()); msgBox.setGeometry(rctMsg); return (msgBox.exec() == QMessageBox::Yes); }
The prototype:
Q_INVOKABLE bool askYesNo(const QString& crstrTitle, const QString& crstrQuestion);
And an example of it being called, which is from JavaScript:
if ( xmleng.askYesNo("Delete record", "Are you sure?") !== true ) { return; }
-
@SPlatten said in QMessageBox::question relative to parent...:
QMessageBox msgBox;
msgBox must have a parent window.
QMainWindow win; win.setWindowTitle("Some window"); win.show(); win.resize(400,300); QMessageBox msgBox(&win); msgBox.setText("Delete record"); msgBox.setInformativeText("Are you sure?\n"); msgBox.setStandardButtons(QMessageBox::Yes); msgBox.addButton(QMessageBox::No); msgBox.setDefaultButton(QMessageBox::No); msgBox.exec();
-
I know for sure that on Windows
msgBox.geometry()
will not work. Only after the dialog is shown will it have a known size. Only after the dialog is shown will the layout be calculated to compute the necessary size. I haven't managed to trick Qt into calculating the layout before the dialog is shown (even though there are specific functions for that). You can try addingmsgBox.show()
before that (but this might be a delayed execution and thus the size will not yet be known in the lines following that. Another approach is to overrideshowEvent
(maybe install an event filter for that) which will center the dialog when it is first shown. The latter is more likely to be successful. -
A parented QMessageBox is displayed centred on its parent by default.
#include <QApplication> #include <QWidget> #include <QMessageBox> #include <QTimer> class Widget: public QWidget { Q_OBJECT public: Widget(QWidget *parent = nullptr): QWidget(parent) { } public slots: void doStuff() { QMessageBox *msgBox = new QMessageBox(this); msgBox->setWindowTitle("In the middle"); msgBox->setText("Delete record"); msgBox->setInformativeText("Are you sure?\n"); msgBox->setStandardButtons(QMessageBox::Yes); msgBox->addButton(QMessageBox::No); msgBox->setDefaultButton(QMessageBox::No); msgBox->exec(); } }; int main(int argc, char **argv) { QApplication app(argc, argv); Widget widget; widget.resize(640, 480); widget.show(); QTimer::singleShot(3000, &widget, &Widget::doStuff); return app.exec(); } #include "main.moc"
Think you can do better positioning then try:
// If you think you can do better than the default QTimer::singleShot(0, [=](){ QRect rctMsg(msgBox->geometry()); rctMsg.moveCenter(this->geometry().center()); msgBox->setGeometry(rctMsg); }); msgBox->exec();