qt dialog



Dialogs are an integral part of GUI programs. Many functional components that cannot or do not fit into the main window must be set in the dialog box. A dialog is usually a top-level window that appears at the top of the program and is used for short-term tasks or concise user interaction. Although the appearance of the Ribbon interface has reduced the use of dialog boxes to a certain extent, we can still find many dialog boxes in the latest version of Office. Therefore, dialogs will remain in our programs for the foreseeable future.

Qt uses the QDialog class to implement dialog boxes. Just like the main window, we usually design a class that inherits QDialog. QDialog (and its subclasses, and all Qt::Dialog-typed classes) have additional interpretations of their parent pointers: if parent is NULL, the dialog acts as a top-level window, otherwise it acts as a parent component's The child dialog (in this case, its default position is the center of the parent). The difference between a top-level window and a non-top-level window is that a top-level window will have its own position in the taskbar, while a non-top-level window will share the position of its parent component.

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    setWindowTitle(tr("Main Window"));

    openAction = new QAction(QIcon(":/images/doc-open"), tr("&Open..."), this);
    openAction->setShortcuts(QKeySequence::Open);
    openAction->setStatusTip(tr("Open an existing file"));
    connect(openAction, &QAction::triggered, this, &MainWindow::open);

    QMenu *file = menuBar()->addMenu(tr("&File"));
    file->addAction(openAction);

    QToolBar *toolBar = addToolBar(tr("&File"));
    toolBar->addAction(openAction);
}

MainWindow::~MainWindow()
{
}

void MainWindow::open()
{
    QDialog dialog;
    dialog.setWindowTitle(tr("Hello, dialog!"));
    dialog.exec();
}
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

Above we used the previous sample code. Pay attention to the contents of the open() function. We create a dialog using QDialog, set its title to "Hello, dialog!", and then call exec() to display it. Note that we are looking at the icon of the taskbar. Since we did not set the parent pointer of the dialog, we will see the position where the dialog appears on the taskbar:
write picture description here

void MainWindow::open()
{
    QDialog dialog(this);
    dialog.setWindowTitle(tr("Hello, dialog!"));
    dialog.exec();
}
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

Re-run it and compare it to see whether the parent pointer has an impact on the QDialog instance.

Dialog boxes are divided into modal dialog boxes and non-modal dialog boxes. A modal dialog box is one that blocks input from other windows in the same application. Modal dialogs are common, such as the "open file" function. You can try the open file of Notepad, when the open file dialog box appears, we cannot operate the window part other than this dialog box. In contrast to this modeless dialog, such as the Find dialog, we can continue to edit the contents of Notepad while the Find dialog is displayed.

Qt supports modal and modeless dialogs. Among them, Qt has two levels of modal dialogs: application-level modal and window-level modal, and the default is application-level modal. Application-level modal means that when a modal dialog box appears, the user must first interact with the dialog box until the dialog box is closed, and then can access other windows in the program. A window-level modal means that the modal only blocks the window associated with the dialog, but still allows the user to interact with other windows in the program. Window-level modals are especially useful for multi-window modes, and a more detailed discussion can be found in a previously published article.

Qt uses QDialog::exec() to implement application-level modal dialogs, QDialog::open() to implement window-level modal dialogs, and QDialog::show() to implement non-modal dialogs. Looking back at our code, in the above example, we called exec() to display the dialog, so this is a modal dialog. When the dialog appears, we cannot have any interaction with the main window until we close the dialog.

Let's try changing exec() to show() to see a modeless dialog:

void MainWindow::open()
{
    QDialog dialog(this);
    dialog.setWindowTitle(tr("Hello, dialog!"));
    dialog.show();
}
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

Did it backfire? The dialog box flashed by! This is because the show() function does not block the current thread, the dialog box is displayed, and the function returns immediately, and the code continues to execute. Note that the dialog is built on the stack, the show() function returns, the MainWindow::open() function ends, the dialog goes out of scope and is destructed, so the dialog disappears. Once you know the reason, it's easy to change. We change the dialog to build on the heap, of course, there is no such problem:

void MainWindow::open()
{
    QDialog *dialog = new QDialog;
    dialog->setWindowTitle(tr("Hello, dialog!"));
    dialog->show();
}
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

For this non-modal dialog and the previous modal dialog. We can interact with the main window when the dialog appears, so we can create multiple identical dialogs:write picture description here

If you are careful enough, you should find that the above code is wrong: there is a memory leak in the dialog! dialog uses new to allocate space on the heap, but there is no delete. The solution is also very simple: assign the pointer of MainWindow to dialog. Remember Qt's object system we talked about earlier?

There's a problem with this, though: what if our dialog doesn't appear in an interface class? Since the parent of a QWidget must be a QWidget pointer, it restricts us from passing a normal C++ class pointer to a Qt dialog. In addition, if there is a strict limit on memory usage, when we use the main window as the parent, the dialog box will not be destroyed if the main window is not closed, so it will always occupy memory. In this scenario, we can set the dialog's WindowAttribute:

void MainWindow::open()
{
    QDialog *dialog = new QDialog;
    dialog->setAttribute(Qt::WA_DeleteOnClose);
    dialog->setWindowTitle(tr("Hello, dialog!"));
    dialog->show();
}
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

The setAttribute() function sets the dialog box to be automatically destroyed when the dialog box is closed. In addition, QObject also has a deleteLater() function, which destroys the dialog box at the end of the current event loop (specifically, you need to use exec() to start a new event loop). About the event loop, we will explain in detail in a later article.

Reprinted from: https://blog.csdn.net/gusgao/article/details/48881133



Dialogs are an integral part of GUI programs. Many functional components that cannot or do not fit into the main window must be set in the dialog box. A dialog is usually a top-level window that appears at the top of the program and is used for short-term tasks or concise user interaction. Although the appearance of the Ribbon interface has reduced the use of dialog boxes to a certain extent, we can still find many dialog boxes in the latest version of Office. Therefore, dialogs will remain in our programs for the foreseeable future.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=324655189&siteId=291194637