9.对话框

Posted lyndonmario

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了9.对话框相关的知识,希望对你有一定的参考价值。

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();
}
27
 
1
MainWindow::MainWindow(QWidget *parent)
2
    : QMainWindow(parent)
3
{
4
    setWindowTitle(tr("Main Window"));
5
 
6
    openAction = new QAction(QIcon(":/images/doc-open"), tr("&Open..."), this);
7
    openAction->setShortcuts(QKeySequence::Open);
8
    openAction->setStatusTip(tr("Open an existing file"));
9
    connect(openAction, &QAction::triggered, this, &MainWindow::open);
10
 
11
    QMenu *file = menuBar()->addMenu(tr("&File"));
12
    file->addAction(openAction);
13
 
14
    QToolBar *toolBar = addToolBar(tr("&File"));
15
    toolBar->addAction(openAction);
16
}
17
 
18
MainWindow::~MainWindow()
19
{
20
}
21
 
22
void MainWindow::open()
23
{
24
    QDialog dialog;
25
    dialog.setWindowTitle(tr("Hello, dialog!"));
26
    dialog.exec();
27
}

1.Qt 中使用QDialog类实现对话框。就像主窗口一样,我们通常会设计一个类继承QDialog


2.QDialog(及其子类,以及所有Qt::Dialog类型的类)的对于其 parent 指针都有额外的解释:如果 parent 为 NULL,则该对话框会作为一个顶层窗口,否则则作为其父组件的子对话框(此时,其默认出现的位置是 parent 的中心)。顶层窗口与非顶层窗口的区别在于,顶层窗口在任务栏会有自己的位置,而非顶层窗口则会共享其父组件的位置。


3.另外在使用Dialog::open();Dialog::show()时,注意不要将Dialog对象建立在栈上,因为dialog是建立在栈上的,一旦show()函数结束返回,MainWindow::open()函数结束,dialog超出作用域被析构,因此对话框立马就消失了。但是我们把对话框建立在堆上就没有这个问题了。

void MainWindow::open()
{
    QDialog dialog(this);
    dialog.setWindowTitle(tr("Hello, dialog!"));
    dialog.show();
}
//这样的写法,出来的窗口不会停留

void MainWindow::open()
{
    QDialog *dialog = new QDialog;
    dialog->setWindowTitle(tr("Hello, dialog!"));
    dialog->show();
}
//这样的窗口才会停留。
15
 
1
void MainWindow::open()
2
{
3
    QDialog dialog(this);
4
    dialog.setWindowTitle(tr("Hello, dialog!"));
5
    dialog.show();
6
}
7
//这样的写法,出来的窗口不会停留
8
9
void MainWindow::open()
10
{
11
    QDialog *dialog = new QDialog;
12
    dialog->setWindowTitle(tr("Hello, dialog!"));
13
    dialog->show();
14
}
15
//这样的窗口才会停留。

4.这样的写法有一个问题就是会存在内存泄漏,因为用new建立后,一直没有delete。
这样的问题的解决思路有两种:
①:把MainWindow的指针赋给dialog即可。但是假如我们的对话框不是在一个类界面出现的呢?这种时候这个方法就不可行。
②:设置dialog的WindowAtrribute
void MainWindow::open()
{
    QDialog *dialog = new QDialog;
    dialog->setAttribute(Qt::WA_DeleteOnClose);
    dialog->setWindowTitle(tr("Hello, dialog!"));
    dialog->show();
}
7
 
1
void MainWindow::open()
2
{
3
    QDialog *dialog = new QDialog;
4
    dialog->setAttribute(Qt::WA_DeleteOnClose);
5
    dialog->setWindowTitle(tr("Hello, dialog!"));
6
    dialog->show();
7
}

技术分享图片

5.另外对于对话框和主窗口之间的传递数据:
①假如是模态窗口(用.exec()的,在.exec()后加返回需要的数据即可)
void MainWindow::open()
{
    QDialog dialog(this);
    dialog.setWindowTitle(tr("Hello, dialog!"));
    dialog.exec();
    qDebug() << dialog.result();
}

因为exec()的返回值是QDialog::Accepted或者QDialog::Rejected,因此也可以用返回值来选择做一些事情。
比如
QDialog dialog(this);
if (dialog.exec() == QDialog::Accepted) {
    // do something
} else {
    // do something else
}
x
1
void MainWindow::open()
2
{
3
    QDialog dialog(this);
4
    dialog.setWindowTitle(tr("Hello, dialog!"));
5
    dialog.exec();
6
    qDebug() << dialog.result();
7
}
8
9
因为exec()的返回值是QDialog::Accepted或者QDialog::Rejected,因此也可以用返回值来选择做一些事情。
10
比如
11
QDialog dialog(this);
12
if (dialog.exec() == QDialog::Accepted) {
13
    // do something
14
} else {
15
    // do something else
16
}
②假如是非模态窗口:
则就无法按照上面那样书写,因为没有阻塞主线程,show()立即返回,用户还没有来得及输入就执行后面的代码,当然不能得到期望的结果。
这里对于非模态窗口,我们运用信号槽机制。
编写一个dialog的继承子类,里面写一个signal。通过connect与MainWindow连接起来。
大体思路可以参考以下代码:
//!!! Qt 5
// in dialog:
void UserAgeDialog::accept()
{
    emit userAgeChanged(newAge); // newAge is an int
    QDialog::accept();
}
 
// in main window:
void MainWindow::showUserAgeDialog()
{
    UserAgeDialog *dialog = new UserAgeDialog(this);
    connect(dialog, &UserAgeDialog::userAgeChanged, this, &MainWindow::setUserAge);
    dialog->show();
}
 
// ...
 
void MainWindow::setUserAge(int age)
{
    userAge = age;
}
1
22
 
1
//!!! Qt 5
2
// in dialog:
3
void UserAgeDialog::accept()
4
{
5
    emit userAgeChanged(newAge); // newAge is an int
6
    QDialog::accept();
7
}
8
 
9
// in main window:
10
void MainWindow::showUserAgeDialog()
11
{
12
    UserAgeDialog *dialog = new UserAgeDialog(this);
13
    connect(dialog, &UserAgeDialog::userAgeChanged, this, &MainWindow::setUserAge);
14
    dialog->show();
15
}
16
 
17
// ...
18
 
19
void MainWindow::setUserAge(int age)
20
{
21
    userAge = age;
22
}

 












以上是关于9.对话框的主要内容,如果未能解决你的问题,请参考以下文章

我该如何做模态对话框片段(代码在我关闭之前不会执行)

将数据从底部工作表对话框片段传递到片段

QT 实用代码片段

从片段类中的对话框添加项目到recyclerview。

片段对话框对活动的松散引用

从底部工作表对话框片段中获取价值