(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)
謝謝