QT对话框

38 篇文章 1 订阅
32 篇文章 0 订阅
QTTest::QTTest(QWidget *parent)
: QMainWindow(parent)
{
setWindowTitle(tr("Mian Window"));
openAction = new QAction(QIcon(":/images/ICon"),tr("&Open..."), this);

openAction->setShortcut(QKeySequence::Open);
openAction->setStatusTip(tr(" Open existed file "));
connect(openAction, &QAction::triggered, this, &QTTest::Open);


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

QMenu *file2 = menuBar()->addMenu(tr("&HELLO"));
file2->addAction(openAction);

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

statusBar();

//ui.setupUi(this);
}

QTTest::~QTTest()
{

}

void QTTest::Open()
{
QDialog dialog; 
dialog.setWindowTitle(tr("hello dailog"));
dialog.exec();
QMessageBox::information(this, tr("Information"), tr("Open"));

}

同样的联系上一章节。将open()函数的里内容改为:

void QTTest::Open()
{
QDialog dialog; 
dialog.setWindowTitle(tr("hello dailog"));
dialog.exec();
QMessageBox::information(this, tr("Information"), tr("Open"));

}

int main(int argc, char *argv[])
{
QApplication   app(argc, argv);

QTTest win; 
win.show();

return app.exec();
}

运行之后,点击File之后便会跳出便会跳出对话框 。

void QTTest::Open()
{
QDialog dialog(this); 
dialog.setWindowTitle(tr("hello dailog"));
dialog.exec();
QMessageBox::information(this, tr("Information"), tr("Open"));

}

重新运行一下,对比一下就会看到 parent 指针的有无对QDialog实例的影响。

对话框分为模态对话框和非模态对话框。所谓模态对话框,就是会阻塞同一应用程序中其它窗口的输入。模态对话框很常见,比如“打开文件”功能。你可以尝试一下记事本的打开文件,当打开文件对话框出现时,我们是不能对除此对话框之外的窗口部分进行操作的。与此相反的是非模态对话框,例如查找对话框,我们可以在显示着查找对话框的同时,继续对记事本的内容进行编辑。

Qt 支持模态对话框和非模态对话框。其中,Qt 有两种级别的模态对话框:应用程序级别的模态和窗口级别的模态,默认是应用程序级别的模态。应用程序级别的模态是指,当该种模态的对话框出现时,用户必须首先对对话框进行交互,直到关闭对话框,然后才能访问程序中其他的窗口。窗口级别的模态是指,该模态仅仅阻塞与对话框关联的窗口,但是依然允许用户与程序中其它窗口交互。窗口级别的模态尤其适用于多窗口模式。

Qt 使用QDialog::exec()实现应用程序级别的模态对话框,使用QDialog::open()实现窗口级别的模态对话框,使用QDialog::show()实现非模态对话框。回顾一下我们的代码,在上面的示例中,我们调用了exec()将对话框显示出来,因此这就是一个模态对话框。当对话框出现时,我们不能与主窗口进行任何交互,直到我们关闭了该对话框。

下面我们试着将 exec() 修改为 show() ,看看非模态对话框:
void QTTest::Open()
{
QDialog dialog(this); 
dialog.setWindowTitle(tr("hello dailog"));
dialog.show();
QMessageBox::information(this, tr("Information"), tr("Open"));
}

对话框竟然一闪而过!这是因为,show()函数不会阻塞当前线程,对话框会显示出来,然后函数立即返回,代码继续执行。注意,dialog 是建立在栈上的,show()函数返回,MainWindow::open()函数结束,dialog 超出作用域被析构,因此对话框消失了。知道了原因就好改了,我们将 dialog 改成堆上建立,当然就没有这个问题了:

void QTTest::Open()
{
QDialog *dialog = new QDialog;
dialog->setWindowTitle(tr("Hello, dialog!"));
dialog->show();
QMessageBox::information(this, tr("Information"), tr("Open"));
}

但是有两个对画框,对比一下这个非模态对话框和之前的模态对话框。我们在对话框出现的时候可以与主窗口交互,因此我们可以建立多个相同的对话框:



非模态对话框可以发现上面的代码有问题:dialog 存在内存泄露!dialog 使用 new 在堆上分配空间,却一直没有 delete。


不过,这样做有一个问题:如果我们的对话框不是在一个界面类中出现呢?由于QWidget的 parent 必须是QWidget指针,那就限制了我们不能将一个普通的 C++ 类指针传给 Qt 对话框。另外,如果对内存占用有严格限制的话,当我们将主窗口作为 parent 时,主窗口不关闭,对话框就不会被销毁,所以会一直占用内存。在这种情景下,我们可以设置 dialog 的WindowAttribute


void QTTest::Open()
{
QDialog *dialog = new QDialog;
dialog->setAttribute(Qt::WA_DeleteOnClose);
dialog->setWindowTitle(tr("Hello, dialog!"));
dialog->show();
QMessageBox::information(this, tr("Information"), tr("Open"));
}


setAttribute()函数设置对话框关闭时,自动销毁对话框。另外,QObject还有一个deleteLater()函数,该函数会在当前事件循环结束时销毁该对话框(具体到这里,需要使用exec()开始一个新的事件循环)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值