QDialog::open()

考虑到前文所述的问题,我们对比一下应用程序级别模态的实现。当windowModality是Qt::NonModal的时候,只需调用QDialog::exec()就可以很容易实现。那么,为什么不提供一个类似的函数,只需简单的调用一下就可以实现一个窗口级别的模态对话框呢?答案就是QDialog::open()。QDialog::open()可以打开一个窗口级别模态对话框。在 Mac OS X 上就是一个 sheet。为了正确实现事件循环,当函数调用之后会立即返回。这意味着你必须通过信号槽机制来实现对返回结果的处理。好在QDialog提供了finished()信号,该信号会正确设置对话框的返回值,类似accept()和reject()。当然,你也可以直接继承QDialog从而使用自己的 signal。那么,对于前面所说的QMessageBox的问题,我们只需使用QMessageBox::open()而不是show(),就可以简单的实现窗口级别模态对话框。即便是在 Mac OS X 平台上,我们也不需要指定Qt::Sheet参数。open()函数是跨平台的,这意味着它能够在所有平台上都以我们所期望的方式运行。现在,我们有了一个更加完善的映射关系:

QDialog::show()=>Qt::NonModal

QDialog::exec()=>Qt::ApplicationModal

QDialog::open()=>Qt::WindowModal

这么一来,选择模态类型比以前简单很多了。下面我们将讲解另外一个令人困惑的问题。

子类的 static 函数

提供新的open()函数的另外一个目的是,避免对 sheet 的误用。这意味着你无需手动设置Qt::Sheet参数。同时,如果你需要打开一个应用程序级别模态的 sheet,那么获得的是一个普通的应用程序级别模态的对话框;这意味着,打开一个窗口级别模态的对话框,系统会为你打开一个 sheet。这是因为在 Cocoa 中,除了 sheet,没有办法打开一个窗口级别模态的普通对话框。

所有应用程序级别模态的对话框都不能使用 sheet 这一事实会影响到所有QDialog子类的 static 函数,例如QColorDialog, QFontDialog,QFileDialog,QInputDialog和QMessageBox。我们考虑其中一个函数,例如QColorDialog::getColor()。这个函数将创建一个QColorDialog对话框,然后模态地显示出来。每个函数的返回值都是用户从对话框中选择的颜色;如果用户没有选择,则会返回一个非法颜色值。这些函数的问题在于,它们提供的是应用程序级别的模态,因此不能使用 sheet。这也许会让一些使用QFileDialog的用户感到困惑,因为在 Mac OS X 下,Qt 的QFileDialog的确是一个 sheet。这是因为 Mac OS X 下,应用程序可以将QFileDialog作为 sheet 使用。

QDialog::open()让我们能够简单地使用三种模态类型。那么,下面让我们看看还有没有另外的函数。的确,我们可以看到open()的很多重载的版本,用于实现一些在过去需要很多代码才能完成的功能。很多子类允许我们方便地向open()函数添加处理返回值的 slot。这些对话框可以进行合适的连接,无需我们处理。下面就是这些重载版本的列表:

QFileDialog::open(QObject *receiver, const char *slot);

QColorDialog::open(QObject *receiver, const char *slot);

QFontDialog::open(QObject *receiver, const char *slot);

QPrintDialog::open(QObject *receiver, const char *slot);

QPageSetupDialog::open(QObject *rec, const char *slot);

QInputDialog::open(QObject *receiver, const char *slot);

QProgressDialog::open(QObject *receiver, const char *slot);

QPrintPreviewDialog::open(QObject *rec, const char *slot);

提供这些函数的目的是,能够方便地连接最常见的处理函数。下面我们将看看这些连接如何进行连接:

QColorDialog将传递进来的 slot 连接到colorSelected(QColor)信号;

QFontDialog连接到fontSelected(QFont)信号;

QFileDialog连接到fileSelected(QString)或者filesSelected(QStringList)信号,这取决于其模式

QProgressDialog连接到canceled()信号。

你可以从 Qt 文档中获得更详细的信息。在open()中指定响应的 slot 可以很好的简化代码。利用这种方法,你可以直接打开一个 native 的对话框,现在提供这个功能的类是QFileDialog,QColorDialog,QFontDialog和QPrintDialog。

新的交互形式

既然我们可以使用open()打开一个 native 的对话框,我们就应该可以类似的使用show()打开一个 native 的非模态对话框。初看起来,这么做并没有什么用,但是它可以在 Mac OS X 下打开一个标准的“live feedback”对话框。这在 Qt 中相当简单。

QDialog子类提供的 static 函数鼓励开发者使用这么一种方式:阻止用户继续工作,并且询问一个问题(例如,“你想用哪个字体?”)。但是,有一定程度上,这将影响到用户的工作,甚至惹恼用户。想象一下用户要使用QColorDialog选择颜色的情景。他需要打开对话框,点击选择颜色,关闭对话框,然后才能看到效果如何。如果他们不满意选择的颜色,则不得不重新进行上面的工作。很显然,这种繁复的工作通常很讨厌,为什么不设计成对话框一直显示在那里,让用户选择好颜色之后就可以马上看到效果呢?一种解决方案是,自己创建一个非模态对话框,实现前面所说的工作。例如在字体选择时,Qt 有一个QFontComboBox类,允许以非模态方式选择字体。但它不可能实现QFontDialog所能做的所有事情。使用对话框更为直观。为了达到这一目的,QFontDialog类提供了QFontDialog::currentFontChanged()信号。我们可以连接到这个信号,然后使用show()提供非模态对话框。这样,我们就有了一个不会打扰用户操作的对话框,能够立刻将相应返回给窗口。QColorDialog同样有类似的方法。这种实现可以让用户感觉程序更加友好。我们以颜色选择为例,看看如何实现这种方式。

class MainWindow

{

Q_OBJECT

//...

private:

// ...

QColorDialog *globalColorDialog;

// ...

};

class PaintArea

{

Q_OBJECT

//...

public slots:

void setBrushColor(const QColor &color);

// ...

};

我们不能使用QColorDialog提供的 static 函数,而是保持一个QColorDialog的指针。为此,我们在主窗口添加一个指针,并且要在组件中添加 slot 函数(这里就是QPaintAreas::setBrushColor())。

void MainWindow::brushColor()

{

if (!globalColorDialog) {

globalColorDialog = new QColorDialog(this);

globalColorDialog->setCurrentColor(paintArea->brushColor());

globalColorDialog->setOption(

QColorDialog::NoButtons, true);

connect(globalColorDialog,

SIGNAL(currentColorChanged(QColor)),

paintArea,

SLOT(setBrushColor(QColor)));

}

globalColorDialog->show();

}

我们需要将选择的颜色设置给当前画笔。使用QColorDialog::NoButtons以避免 OK 和 Cancel 按钮出现。这主要是因为在这种实现方式中,它们并没有什么意义,因为我们要将选择的颜色立即返回给画笔(取消按钮是不能撤销颜色选择的)。但是,在 X11 的某些窗口管理器上,没有关闭按钮的窗口会变得很奇怪,这一点值得注意。最后,我们创建currentColorChanged()和setBrushColor()的信号槽连接。然后调用show()函数显示对话框。如果对话框已经显示,则简单地将其放置在窗口最顶层。

对于QFontDialog也是类似的,没有什么区别。我们创建一个字体对话框,通过保持其指针来做信号槽连接。

结论

这篇文章阐述了一些使用QDialog的新的方法。我们着重讲述了各种模态的实现,以及一些有用的技巧。这里提到的函数有些是 Qt 4.5 之后新增加的,例如QDialog::open(),这些函数都很有用,所以我们应该在自己的程序中多多使用,而不是固守于旧的接口。毕竟,我们的程序也需要与时俱进的~

qdialog 返回值_QDialog 窗口级别模态(续)相关推荐

  1. qdialog 返回值_QDialog exec()并获取结果值

    我有子类QDialog来实现类似于QMessageBox的功能(我需要这个来允许定制).它有一条短信和"确定"."取消"按钮.我正在显示使用exec()使其阻塞 ...

  2. qdialog 返回值_Qt对话框QDialog

    QDialog是Qt中所有对话框窗口的基类 当QWidget无父组件的时候作为一个独立的窗口,有父组件的时候,将作为一个可见的部件嵌入到父组件里面. QDialog不能作为子部件嵌入到其他容器中 对话 ...

  3. qdialog 返回值_PyQt5 中QDialog值传递

    在应用PyQt5设计GUI界面时,经常会遇到输入或选择多个参数的问题,把它写到一个窗体中,会显得主窗体很臃肿.所以一般是添加一个按钮,调用对话框,将这些参数选择放入弹出的对话框中,关闭对话框时将参数值 ...

  4. qdialog 返回值_PyQt QDialog-返回值并从对话框关闭

    我正在PyQt中开发一个用户界面,在尝试使用QDialog时遇到了一些问题.本质上,我有一个主小部件和一个子小部件,保存在单独的.py文件中:我希望子小部件在单击主小部件中的某个按钮时打开.这看起来开 ...

  5. qdialog 返回值_PyQt QDialog - 返回一个值并从对话框中关闭

    我正在PyQt的用户界面上工作,我遇到了一些试图使用QDialog的问题.基本上我有一个主小部件和一个子小部件,保存在单独的.py文件中;当我点击主窗口小部件中的某个按钮时,我想要打开子窗口小部件.这 ...

  6. qdialog 返回值_c – QDialog exec()并获取结果值

    我已经将QDialog子类化为实现类似于QMessageBox的功能(我需要这个以允许自定义).它有一条短信和OK,取消按钮.我正在使用exec()显示对话框以使其阻止.现在,当用户单击"确 ...

  7. qdialog 返回值_如何从Python中的QDialog实例返回值?

    我想打开一个QtGui.QDialog,从用户请求一组值,然后在单击"保存"后返回值.在 下面的代码应该在不修改的情况下运行.在import sys from PySide imp ...

  8. qdialog 返回值_qt - QDialog :: exec()的返回值始终是QDialog :: Rejected - 堆栈内存溢出...

    我有一个从QDialog派生的对话框AlarmSetup,其按钮设置如下: // button box buttonBox = new QDialogButtonBox(QDialogButtonBo ...

  9. qdialog 返回值_python-PyQt QDialog返回响应是或否

    我有一个QDialog类 confirmation_dialog = uic.loadUiType("ui\confirmation_dialog.ui")[0] class Co ...

最新文章

  1. tryexceptelse可以嵌套
  2. 影响国家安全的四项新兴技术
  3. 如何替换字符串中出现的所有字符?
  4. 【转】更简单的非递归遍历二叉树的方法
  5. 【PM模块】维护订单基本处理流程——实际操作
  6. CTF-压缩包密码CRC爆解工具安装
  7. wireMock快速伪造restful服务
  8. 【codevs2488】绿豆蛙的归宿
  9. Springboot中@ComponentScan 注解
  10. 信息学奥赛一本通(1161:转进制)
  11. 如何使用Pinterest新推出的功能Rich Pin
  12. 蒟蒻吃药计划-治疗系列 #round6 数据结构初步-指针|链表|结构体
  13. 计算机网络之码元、波特、速率与带宽
  14. Python 数据结构与算法——插入排序(insertion sort)
  15. 2019.7.26随堂笔记
  16. 织梦dedecms 模板代码标签学习
  17. ppt画深度学习网络图-立体网络模块
  18. 腾讯T3手把手教你!Flutter尽然还能有这种操作!全套教学资料
  19. 新一代国产区块链底层平台正式亮相,蓝石区块链实验室首发CefaChain技术 | 附白皮书
  20. TOEFL新托福写作的 11 种常见错误分析

热门文章

  1. 【一棵开花的树】 席慕容
  2. 【无标题】C# WPF如何反射加载Geometry几何图形数据图标学习通http://www.bdgxy.com/
  3. 小米MIUI系统四大实用技巧,小米手机不白买
  4. 大数据入门:WordCount程序解析
  5. RestTemplate POST请求发送文件
  6. 初级驱动调试笔记-总结
  7. 【- Flutter Web篇 -】 FlutterUnit web版闪亮登场 ,android的开发语言
  8. C# CheckedListBox控件的使用方法
  9. 更改GROOVE的文件夹位置
  10. SVN 删除文件后恢复