(1)消息对话框里,分为通知消息,询问消息,提醒消息,错误消息。可以直接使用本类的静态函数,简单。但 QT 的官方说明里,建议使用动态成员函数组件的消息框,而非使用静态函数。理由是静态函数里无法携带更多的文本内容。但基于 QMessageBox 的功能来定制消息框,更难。
++
++
++
++还有很多的成员函数,来管理消息框里的按钮,涉及按钮的增删改查。就不一一列举了,感觉这不容易的知识。暂时不深学了。
(2)接着学习最后的静态成员函数 :
++测试一下 :
(3)本源代码定义于头文件 qmessagebox . h :
#ifndef QMESSAGEBOX_H
#define QMESSAGEBOX_H#include <QtWidgets/qtwidgetsglobal.h>#include <QtWidgets/qdialog.h>QT_REQUIRE_CONFIG(messagebox);QT_BEGIN_NAMESPACEclass QLabel;
class QMessageBoxPrivate;
class QAbstractButton;
class QCheckBox;/*
The QMessageBox class provides a modal dialog for informing the user orfor asking the user a question and receiving an answer.Detailed Description :
-个消息框会显示主要文本以提醒用户某种情况,
进一步的说明性文本以进一步解释提醒内容或询问用户问题,
以及可选的详细文本以在用户请求时提供更多的数据。消息框还可以显示图标和用于接受用户响应的标准按钮。提供了两种使用QMessageBox的API,即基于属性的API和静态函数。
调用静态函数是更简单的方法,但其灵活性不如使用基于属性的API,且显示结果的信息量也较小。
建议使用基于属性的API。The Property-based API :
要使用基于属性的API,首先需要构造一个QMessageBox的实例,然后设置所需的属性,
最后调用exec()来显示消息。最简单的配置方式仅设置消息文本属性。QMessageBox msgBox;msgBox.setText("The document has been modified.");msgBox.exec();用户必须点击OK按钮才能关闭消息框。在消息框被关闭之前,其余的GUI将保持锁定状态。dismiss解散。-个更好的方法不仅在于提醒用户注意某个事件,还在于询问用户对此应采取何种行动。
将这个问题存储在“信息文本属性”中,并将“标准按钮属性”设置为您想要的按钮集合,作为用户可能的响应选项。
这些按钮是通过使用按位或运算符结合来自“标准按钮”的值来指定的。
按钮的显示顺序取决于平台。例如,在Windows上,“保存”按钮会显示在“取消”按钮的左侧,
而在MacOS上,顺序则相反。
标记其中一个标准按钮为默认按钮。QMessageBox msgBox;msgBox.setText("The document has been modified.");msgBox.setInformativeText("Do you want to save your changes?");msgBox.setStandardButtons(QMessageBox::Save | QMessageBox::Discard| QMessageBox::Cancel );msgBox.setDefaultButton(QMessageBox::Save);int ret = msgBox.exec();这是《macOS指南》中推荐的做法。类似的指南也适用于其他平台,
但请注意不同平台在处理信息文本时的不同方式。exec()插槽返回被点击按钮的标准按钮 StandardButtons 值。switch (ret) {case QMessageBox::Save: // Save was clickedbreak;case QMessageBox::Discard: // Don't Save was clickedbreak;case QMessageBox::Cancel: // Cancel was clickedbreak;default: // should never be reached 这一条不应被达到break;}为了向用户提供更多信息,以便他回答问题,应设置详细的 detailed text 文本属性。
如果设置了详细的 detailed text 文本属性, Show Details... 按钮将会显示。
Clicking the Show Details... button displays the detailed text.Rich Text and the Text Format Property :
详细文本 detailed text 属性总是被解释为纯文本。
主文本 main text 和信息文本 informative text 属性可以是纯文本或富文本。
这些字符串将根据文本格式 text format 属性的设置来解释。默认设置为自动文本 auto-text。请注意,对于某些包含XML元字符的纯文本字符串,
自动文本 auto-text,富文本检测测试 rich text detection test 可能会失败,
导致纯文本字符串被错误地解释为富文本。
在这些罕见的情况下,使用Qt::convertFromPlainText()将纯文本字符串转换为视觉上等效的富文本字符串,
或者使用setTextFormat()显式地设置文本格式 text format 属性。Severity Levels and the Icon and Pixmap Properties :
QMessageBox支持四种预定义的讯息严重程度级别或讯息类型,
实际上它们之间的区别仅在于各自显示的预定义图标.
通过将图标 icon属性设置为预定义的图标之一,可以指定这四种预定义讯息 predefined icons类型之一。
以下规则仅供参考:
i Information For reporting information about normal operations.
问号? Question For asking a question during normal operations.
叹号! Warning For reporting non-critical errors.
叉 X Critical For reporting critical errors.预定义的图标并非由 QMessageBox定义,而是由样式提供。默认值为 NoIcon。
在所有情况下,消息框在其他方面是相同的。
在使用标准图标时,应采用表格中推荐的那个,或者采用适用于您平台的相关样式指南所推荐的那个。
如果没有任何标准图标适合您的消息框,您可以通过设置 icon pixmap属性(而非图标icon属性)来使用自定义图标。总之,要设置图标,请使用setIcon()为标准图标之一设置图标,或者使用setIconPixmap()为自定义图标设置图标。The Static Functions API :
使用静态函数API构建消息框虽然方便,但其灵活性却不如使用基于属性的API,
因为静态函数签名中缺少用于设置信息性文本 informative text 和详细文本 detailed text 属性的参数。
一个变通方法是使用“标题title”参数作为消息框的主文本,而使用“文本text”参数作为消息框的信息性文本。
由于这种做法有明显的缺点,导致消息框的可读性降低,因此平台指南并不推荐使用。
微软Windows用户界面指南建议使用应用程序名称 application name 作为窗口的标题 window's title,
这意味着如果您除了主文本外还有一个信息性文本,您必须将其连接到text参数。请注意,静态函数签名相对于其按钮参数已有所更改,
这些参数现在用于设置标准按钮 standard buttons 和默认按钮 default button。静态函数可用于创建信息框information()、问题框question()、警告框warning()和关键消息框critical()。int ret = QMessageBox::warning(this, tr("My Application"),tr("The document has been modified.\n Do you want to save your changes?"),QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel,QMessageBox::Save);标准对话框示例展示了如何使用QMessageBox和其他内置的Qt对话框。Advanced Usage :
如果标准按钮 standard buttons不足以满足您的消息框需求,
您可以使用带文本和按钮角色 buttonRole 的`addButton()、重载函函数来添加自定义按钮。
`ButtonRole`由`QMessageBox`用于确定屏幕上按钮的排列顺序(各平台有所不同)。
在调用`exec()、后,您可以测试`clickedButton()、的值。例如:QMessageBox msgBox;QPushButton * connectButton = msgBox.addButton(tr("Connect"), QMessageBox::ActionRole);QPushButton * abortButton = msgBox.addButton(QMessageBox::Abort);msgBox.exec();if (msgBox.clickedButton() == connectButton) { // connect} else if (msgBox.clickedButton() == abortButton) { // abort}Default and Escape Keys :
使用`setDefaultButton()、可以指定默认按钮(即按下Enter键时激活的按钮)。
如果没有指定默认按钮,`QMessageBox`会根据对话框中使用的按钮的按钮角色button roles尝试找到相应的默认按钮。逃逸 escape 按钮(即按下 Esc 键时激活的按钮)可以使用 setEscapeButton()方法来指定。
如果没有指定逃逸按钮QMessageBox会尝试根据以下规则找到合适的按钮:
1.如果只有一个按钮,则该按钮在按下ESc时被激活。
2.如果有一个取消 Cancel按钮,它就是按下ESc时激活的按钮。
3.如果恰好有一个按钮具有拒绝角色 the Reject role或否定角色the the No role,则该按钮在按下ESc时被激活。
当无法通过这些规则确定退出按钮时,按下ESc没有效果。*/class Q_WIDGETS_EXPORT QMessageBox : public QDialog
{Q_OBJECT/*此属性持有消息框的图标消息框的图标可以通过以下值之一指定:QMessageBox::NoIconQMessageBox::问题QMessageBox::信息QMessageBox::警告 warningQMessageBox::Critical默认值是QMessageBox::NoIcon。用于显示实际图标的像素图取决于当前的GUI样式。您还可以通过设置 iconPixmap属性来为图标设置自定义像素图。*/Q_PROPERTY(Icon icon READ icon WRITE setIcon) //官方图标Q_PROPERTY(QPixmap iconPixmap READ iconPixmap WRITE setIconPixmap) //自定义图标/*此属性持有当前图标。消息框当前使用的图标。请注意,通常很难绘制一个在所有GUI风格中都显得合适的像素图。您可能需要在每个平台上提供不同的像素图。默认情况下,此属性未定义。*///class QLabel::Q_PROPERTY(Qt::TextFormat textFormat ...)//这个枚举用于可以同时显示纯文本和富文本的小部件中,例如QLabel。//它用于决定是否将文本字符串解释为其中之一或另一种。//这通常是通过将一个eum值传递给 QTextEdit::setTextFormat ()函数来完成的。// enum Qt::TextFormat { //这是 label 上文本的格式// PlainText, //文本字符串被解释为一个普通文本字符串。// RichText, //文本字符串被解释为富文本字符串。请参阅支持的HTML子集以获取富文本的定义。// AutoText, //如果Qt::mayBeRichText()返回true,// //则将文本字符串解释为Qt::RichText;否则,将其解释为Qt::PlainText.// MarkdownText //文本字符串被解释为Markdown格式化的文本。此枚举值在Qt5.14中添加。//};Q_PROPERTY(Qt::TextFormat textFormat //默认格式为Qt::AutoText。READ textFormat WRITE setTextFormat)//此属性保存消息框显示文本的格式。消息框当前使用的文本格式。/*此属性持有要显示的消息框文本。文本将被解释为纯文本或富文本,具体取决于文本格式设置(QMessageBox::textFormat).默认设置为 Qt::AutoText,即消息框将尝试自动检测文本的格式。此属性的默认值为空字符串。*/Q_PROPERTY(QString textREAD text WRITE setText)/*此属性包含提供消息更详细描述的信息文本。说明性文本可以用来扩展`text()',以向用户提供更多信息。在Mac上,该文本会显示在`text()、下方,采用小型系统字体。在其他平台上,它只是被附加到已有的文本上。默认情况下,此属性包含一个空字符串。*/Q_PROPERTY(QString informativeTextREAD informativeText WRITE setInformativeText)Q_PROPERTY(QString detailedTextREAD detailedText WRITE setDetailedText)/*此属性包含在详细信息区域中要显示的文本。文本将被解释为纯文本。默认情况下,此属性包含一个空字符串。*///指定消息框标签应如何与用户输入交互。默认值取决于样式。Q_PROPERTY(Qt::TextInteractionFlags textInteractionFlagsREAD textInteractionFlagsWRITE setTextInteractionFlags)/*//QLabel :: Q_PROPERTY(Qt::TextInteractionFlags textInteractionFlags// READ textInteractionFlags WRITE setTextInteractionFlags)//本枚举类应用于标签的 属性 textInteractionFlags.本属性也用于文本框.//这个枚举定义了文本显示控件如何对用户输入做出反应。enum Qt::TextInteractionFlag {NoTextInteraction = 0, //无法与文本进行交互。TextSelectableByMouse = 1, //文本可以通过鼠标选择,//并使用上下文菜单或标准键盘快捷键复制到剪贴板。TextSelectableByKeyboard = 2, //可以通过键盘上的光标键选择文本。显示一个文本光标。LinksAccessibleByMouse = 4, //链接可以通过鼠标进行高亮和激活。LinksAccessibleByKeyboard = 8, //链接可以通过按Tab键进行聚焦,并通过按Enter键激活。TextEditable = 16,//文本可以完全编辑。TextEditorInteraction = TextSelectableByMouse| TextSelectableByKeyboard| TextEditable, //default for a text editor.TextBrowserInteraction = TextSelectableByMouse //default for QTextBrowser.| LinksAccessibleByMouse| LinksAccessibleByKeyboard};Q_DECLARE_FLAGS(TextInteractionFlags, TextInteractionFlag)Q_DECLARE_OPERATORS_FOR_FLAGS(TextInteractionFlags)*///消息框中标准按钮的集合.此属性控制消息框使用的标准按钮。默认情况下,此属性不包含任何标准按钮。Q_PROPERTY(StandardButtons standardButtonsREAD standardButtonsWRITE setStandardButtons)protected:bool event(QEvent * e ) override;void resizeEvent(QResizeEvent * event) override;void showEvent(QShowEvent * event) override;void closeEvent(QCloseEvent * event) override;void keyPressEvent(QKeyEvent * event) override;void changeEvent(QEvent * event) override;private:Q_PRIVATE_SLOT(d_func(), void _q_buttonClicked(QAbstractButton *))Q_PRIVATE_SLOT(d_func(), void _q_clicked(QPlatformDialogHelper::StandardButton,QPlatformDialogHelper::ButtonRole))Q_DISABLE_COPY(QMessageBox)Q_DECLARE_PRIVATE(QMessageBox)Q_SIGNALS:void buttonClicked(QAbstractButton * button);public :using QDialog::open; //将对话框显示为窗口模态 window modal dialog对话框,并立即返回。//virtual void QDialog::open();void open(QObject * receiver, const char * member); //信息与槽函数//Opens the dialog and connects its finished() or buttonClicked() signal to the// slot specified by receiver and member.//If the slot in member has a pointer for its first parameter, //若槽函数的形参一是指针,// the connection is to buttonClicked(), //则连接到 buttonClicked(ptr)信号函数;// otherwise the connection is to finished(). //否则连接到 finished(int)信号函数//The signal will be disconnected from the slot when the dialog is closed.public:explicit QMessageBox(QWidget * parent = nullptr);QMessageBox(Icon icon, const QString & title, const QString & text,StandardButtons buttons = NoButton, QWidget * parent = nullptr,Qt::WindowFlags flags = Qt::Dialog | Qt::MSWindowsFixedSizeDialogHint);~QMessageBox();enum Icon { // keep this in sync with QMessageDialogOptions::IconNoIcon = 0,Information = 1, //表明这条消息没有什么特别之处。Warning = 2, //表示该消息是警告,但可以处理。Critical = 3, //表明该消息代表了一个关键问题。Question = 4 //表明该消息正在提出一个问题。};Q_ENUM(Icon)
// Q_PROPERTY(Icon icon
// READ icon WRITE setIcon) //官方图标Icon icon() const;void setIcon(Icon);// Q_PROPERTY(QPixmap iconPixmap
// READ iconPixmap WRITE setIconPixmap) //自定义图标QPixmap iconPixmap() const;void setIconPixmap(const QPixmap &pixmap);// // enum Qt::TextFormat { PlainText, RichText, AutoText, MarkdownText };
// Q_PROPERTY(Qt::TextFormat textFormat //默认格式为Qt::AutoText。
// READ textFormat WRITE setTextFormat)Qt::TextFormat textFormat() const;void setTextFormat(Qt::TextFormat format);// Q_PROPERTY(QString text // 最基础的消息文本
// READ text WRITE setText)QString text() const;void setText(const QString & text);// Q_PROPERTY(QString informativeText //更详细描述的信息文本
// READ informativeText WRITE setInformativeText)QString informativeText() const;void setInformativeText(const QString & text);// Q_PROPERTY(QString detailedText //detailed 中的文本
// READ detailedText WRITE setDetailedText)QString detailedText() const;void setDetailedText(const QString & text);// //指定消息框标签应如何与用户输入交互,如何选中,如何编辑,是否打开超链接等等。默认值取决于样式。
// Q_PROPERTY(Qt::TextInteractionFlags textInteractionFlags
// READ textInteractionFlags
// WRITE setTextInteractionFlags)Qt::TextInteractionFlags textInteractionFlags() const;void setTextInteractionFlags(Qt::TextInteractionFlags flags);//keep this in sync with QDialogButtonBox::StandardButton and// QPlatformDialogHelper::StandardButton//这些枚举描述了标准按钮的标志。每个按钮都有一个定义的ButtonRole。enum StandardButton {NoButton = 0x00000000,Ok = 0x00000400,Save = 0x00000800,SaveAll = 0x00001000,Open = 0x00002000,Yes = 0x00004000,YesToAll = 0x00008000,No = 0x00010000,NoToAll = 0x00020000,Abort = 0x00040000,Retry = 0x00080000,Ignore = 0x00100000,Close = 0x00200000,Cancel = 0x00400000,Discard = 0x00800000,Help = 0x01000000,Apply = 0x02000000,Reset = 0x04000000,RestoreDefaults = 0x08000000,FirstButton = Ok, // internalLastButton = RestoreDefaults, // internalYesAll = YesToAll, // obsolete 过时的NoAll = NoToAll, // obsoleteDefault = 0x00000100, // obsoleteEscape = 0x00000200, // obsoleteFlagMask = 0x00000300, // obsoleteButtonMask = ~FlagMask // obsolete};typedef StandardButton Button; //在 Qt7以下有此定义Q_DECLARE_FLAGS(StandardButtons, StandardButton)Q_FLAG(StandardButtons)
// Q_PROPERTY(StandardButtons standardButtons //消息框中标准按钮的集合.
// READ standardButtons
// WRITE setStandardButtons)StandardButtons standardButtons() const;StandardButton standardButton(QAbstractButton * button ) const;void setStandardButtons(StandardButtons buttons);void setWindowTitle (const QString & title);void setWindowModality(Qt::WindowModality windowModality);//enum Qt::WindowModality { NonModal, WindowModal, ApplicationModal };//返回对话框中显示的复选框。如果没有设置复选框,则为nullptr。QCheckBox * checkBox() const;void setCheckBox(QCheckBox * cb);//在消息对话框上设置复选框 cb。该消息框将拥有复选框的权限take ownership。//参数cb可以设为 nullptr,以从消息框中移除现有的复选框。//这个枚举描述了可用于描述按钮盒中按钮的角色。这些角色的组合用作标志,以描述其行为的不同方面。// keep this in sync with QDialogButtonBox::ButtonRole and// QPlatformDialogHelper::ButtonRoleenum ButtonRole {InvalidRole = -1, //The button is invalid.//Clicking the button causes the dialog to be accepted (e.g. OK).AcceptRole, //点击按钮会接受对话框(例如:确定)//Clicking the button causes the dialog to be rejected (e.g. Cancel).RejectRole,DestructiveRole, //点击按钮会导致破坏性更改(例如,放弃更改)并关闭对话框。ActionRole, //点击按钮会改变对话框中的元素。HelpRole, //可以点击按钮请求帮助。YesRole, //The button is a "Yes"-like button.NoRole, //The button is a "No"-like button.ResetRole, //该按钮将对话框的字段重置为默认值。ApplyRole, //The button applies current changes.NRoles};//返回一个指向标准按钮 which的指针,如果此消息框中不存在标准按钮,则返回nullptr。QAbstractButton * button (StandardButton which ) const;QAbstractButton * clickedButton () const; //返回用户点击的按钮,//如果用户按下了 ESc键且未设置 escape button按钮,则返回nullptr。//如果exec()尚未被调用,返回nullptr。QList<QAbstractButton *> buttons() const; //返回已添加到消息框的所有按钮的列表。ButtonRole buttonRole(QAbstractButton * button) const;//返回指定按钮的按钮角色。如果按钮为空指针或尚未添加到消息框中,此函数将返回InvalidRole。//Adds a standard button to the message box if it is valid to do so,// and returns the push button.QPushButton * addButton(StandardButton button);//Adds the given button to the message box with the specified role.void addButton(QAbstractButton * button, ButtonRole role);QPushButton * addButton(const QString & text , ButtonRole role);//Creates a button with the given text,// adds it to the message box for the specified role, and returns it.void removeButton(QAbstractButton * button);//Removes button from the button box without deleting it.QPushButton * defaultButton() const;void setDefaultButton(QPushButton * button);void setDefaultButton(StandardButton button);QAbstractButton * escapeButton() const; //在上面的总注释里有一些介绍void setEscapeButton(QAbstractButton * button);void setEscapeButton(StandardButton button);//*******************************************************************************
//**************************以下是重要的静态成员函数*********************************
//**************************返回值是枚举量的是新函数*********************************
//*******************************************************************************static StandardButton information(QWidget * parent, const QString & title,const QString & text, StandardButtons buttons = Ok, //通知消息StandardButton defaultButton = NoButton);// needed as long as we have int overloads //在 Qt7以下有此定义inline static StandardButton information(QWidget *parent, const QString &title,const QString& text,StandardButton button0, StandardButton button1 = NoButton){ return information(parent, title, text, StandardButtons(button0), button1); }static StandardButton question (QWidget * parent, const QString & title,const QString & text, StandardButtons buttons = StandardButtons(Yes | No),StandardButton defaultButton = NoButton); //询问消息inline static int question(QWidget *parent, const QString &title, //在 Qt7以下有此定义const QString& text,StandardButton button0, StandardButton button1){ return question(parent, title, text, StandardButtons(button0), button1); }static StandardButton warning (QWidget * parent, const QString & title,const QString & text, StandardButtons buttons = Ok, //警告消息StandardButton defaultButton = NoButton);inline static int warning(QWidget *parent, const QString &title, //在 Qt7以下有此定义const QString& text,StandardButton button0, StandardButton button1){ return warning(parent, title, text, StandardButtons(button0), button1); }static StandardButton critical (QWidget * parent, const QString & title,const QString & text, StandardButtons buttons = Ok, //错误消息StandardButton defaultButton = NoButton);inline static int critical(QWidget *parent, const QString &title, //在 Qt7以下有此定义const QString& text,StandardButton button0, StandardButton button1){ return critical(parent, title, text, StandardButtons(button0), button1); }static void about (QWidget * parent, const QString & title, const QString & text);static void aboutQt(QWidget * parent, const QString & title = QString());#if QT_DEPRECATED_SINCE(6,2) //有此定义,都是 QT6.2 里过时的函数,略// the following functions are obsolete 过时的:
#endif}; //完结 class QMessageBox : public QDialogQ_DECLARE_OPERATORS_FOR_FLAGS(QMessageBox::StandardButtons)#define QT_REQUIRE_VERSION(argc, argv, str) { QString s = QString::fromLatin1(str);\
QString sq = QString::fromLatin1(qVersion()); \
if ((sq.section(QChar::fromLatin1('.'),0,0).toInt()<<16)+\
(sq.section(QChar::fromLatin1('.'),1,1).toInt()<<8)+\
sq.section(QChar::fromLatin1('.'),2,2).toInt()<(s.section(QChar::fromLatin1('.'),0,0).toInt()<<16)+\
(s.section(QChar::fromLatin1('.'),1,1).toInt()<<8)+\
s.section(QChar::fromLatin1('.'),2,2).toInt()) { \
if (!qApp){ \new QApplication(argc,argv); \
} \
QString s = QApplication::tr("Executable '%1' requires Qt "\"%2, found Qt %3.").arg(qAppName()).arg(QString::fromLatin1(\
str)).arg(QString::fromLatin1(qVersion())); QMessageBox::critical(0, QApplication::tr(\
"Incompatible Qt Library Error"), s, QMessageBox::Abort, 0); qFatal("%s", s.toLatin1().data()); }}QT_END_NAMESPACE#endif // QMESSAGEBOX_H
(4)
谢谢