Qt是目前最先进、最完整的跨平台C开发工具。它不仅完全实现了一次编写所有平台无差别运行更提供了几乎所有开发过程中需要用到的工具。如今Qt已被运用于超过70个行业、数千家企业支持数百万设备及应用。窗口标志要么是类型要么是提示。类型用于为小部件指定各种窗口系统属性一个小部件只能有一种类型默认是Qt::Widget但是小部件可以有零个或多个提示提示用于自定义顶级窗口的外观。小部件的标志存储在Qt::WindowFlags类型中该类型存储标志的OR组合。这个例子由两个类组成ControllerWindow是主要的应用程序小部件它允许用户在可用的窗口标志中进行选择并在单独的预览窗口中显示效果。PreviewWindow是一个自定义小部件在只读文本编辑器中显示当前设置的窗口标志的名称。我们将从回顾ControllerWindow类开始然后再看看PreviewWindow类。ControllerWindow类定义class ControllerWindow : public QWidget { Q_OBJECT public: ControllerWindow(QWidget *parent nullptr); private slots: void updatePreview(); private: void createTypeGroupBox(); void createHintsGroupBox(); QCheckBox *createCheckBox(const QString text); QRadioButton *createRadioButton(const QString text); PreviewWindow *previewWindow; QGroupBox *typeGroupBox; QGroupBox *hintsGroupBox; QPushButton *quitButton; QRadioButton *windowRadioButton; QRadioButton *dialogRadioButton; QRadioButton *sheetRadioButton; QRadioButton *drawerRadioButton; QRadioButton *popupRadioButton; QRadioButton *toolRadioButton; QRadioButton *toolTipRadioButton; QRadioButton *splashScreenRadioButton; QCheckBox *msWindowsFixedSizeDialogCheckBox; QCheckBox *x11BypassWindowManagerCheckBox; QCheckBox *framelessWindowCheckBox; QCheckBox *windowNoShadowCheckBox; QCheckBox *windowTitleCheckBox; QCheckBox *windowSystemMenuCheckBox; QCheckBox *windowMinimizeButtonCheckBox; QCheckBox *windowMaximizeButtonCheckBox; QCheckBox *windowCloseButtonCheckBox; QCheckBox *windowContextHelpButtonCheckBox; QCheckBox *windowShadeButtonCheckBox; QCheckBox *windowStaysOnTopCheckBox; QCheckBox *windowStaysOnBottomCheckBox; QCheckBox *customizeWindowHintCheckBox; };ControllerWindow类继承了QWidget该小部件允许用户在可用的窗口标志中进行选择并在单独的预览窗口中显示效果。我们声明了一个私有updatePreview()槽以便在用户更改窗口标志时刷新预览窗口。我们还声明了几个私有函数来简化构造函数调用createTypeGroupBox()函数使用私有createButton()函数为每个可用的窗口类型创建一个单选按钮并将它们收集到一个组框中。以类似的方式我们使用createHintsGroupBox()函数为每个可用的提示创建一个复选框使用私有的createCheckBox()函数。除了各种单选按钮和复选框之外我们还需要一个相关的PreviewWindow来显示当前选择的窗口标志的效果。ControllerWindow类实现ControllerWindow::ControllerWindow(QWidget *parent) : QWidget(parent) { previewWindow new PreviewWindow(this); createTypeGroupBox(); createHintsGroupBox(); quitButton new QPushButton(tr(Quit)); connect(quitButton, QPushButton::clicked, qApp, QCoreApplication::quit); QHBoxLayout *bottomLayout new QHBoxLayout; bottomLayout-addStretch(); bottomLayout-addWidget(quitButton); QHBoxLayout *mainLayout new QHBoxLayout; mainLayout-addWidget(typeGroupBox); mainLayout-addWidget(hintsGroupBox); mainLayout-addLayout(bottomLayout); setLayout(mainLayout); setWindowTitle(tr(Window Flags)); updatePreview(); }在构造函数中我们首先创建预览窗口。然后使用私有的createTypeGroupBox()和createHintsGroupBox()函数创建包含可用窗口标志的组框。此外我们还创建了一个Quit按钮将按钮和一个可伸缩空间放在一个单独的布局中来使按钮出现在WindowFlag小部件的右下角。最后我们将按钮的布局和两个组框添加到QVBoxLayout中设置窗口标题并使用updatePreview()槽刷新预览窗口。void ControllerWindow::updatePreview() { Qt::WindowFlags flags; if (windowRadioButton-isChecked()) flags Qt::Window; else if (dialogRadioButton-isChecked()) flags Qt::Dialog; else if (sheetRadioButton-isChecked()) flags Qt::Sheet; else if (drawerRadioButton-isChecked()) flags Qt::Drawer; else if (popupRadioButton-isChecked()) flags Qt::Popup; else if (toolRadioButton-isChecked()) flags Qt::Tool; else if (toolTipRadioButton-isChecked()) flags Qt::ToolTip; else if (splashScreenRadioButton-isChecked()) flags Qt::SplashScreen;每当用户更改任何窗口标志时就调用updatePreview()插槽。首先我们创建一个空Qt::WindowFlags标志然后确定要检查的类型并将其添加到标志中。if (msWindowsFixedSizeDialogCheckBox-isChecked()) flags | Qt::MSWindowsFixedSizeDialogHint; if (x11BypassWindowManagerCheckBox-isChecked()) flags | Qt::X11BypassWindowManagerHint; if (framelessWindowCheckBox-isChecked()) flags | Qt::FramelessWindowHint; if (windowNoShadowCheckBox-isChecked()) flags | Qt::NoDropShadowWindowHint; if (windowTitleCheckBox-isChecked()) flags | Qt::WindowTitleHint; if (windowSystemMenuCheckBox-isChecked()) flags | Qt::WindowSystemMenuHint; if (windowMinimizeButtonCheckBox-isChecked()) flags | Qt::WindowMinimizeButtonHint; if (windowMaximizeButtonCheckBox-isChecked()) flags | Qt::WindowMaximizeButtonHint; if (windowCloseButtonCheckBox-isChecked()) flags | Qt::WindowCloseButtonHint; if (windowContextHelpButtonCheckBox-isChecked()) flags | Qt::WindowContextHelpButtonHint; if (windowShadeButtonCheckBox-isChecked()) flags | Qt::WindowShadeButtonHint; if (windowStaysOnTopCheckBox-isChecked()) flags | Qt::WindowStaysOnTopHint; if (windowStaysOnBottomCheckBox-isChecked()) flags | Qt::WindowStaysOnBottomHint; if (customizeWindowHintCheckBox-isChecked()) flags | Qt::CustomizeWindowHint; previewWindow-setWindowFlags(flags);我们还确定哪些暗示的检查并将它们添加到标记使用的OR操作符使用标志来设置预览窗口的窗口标志。QPoint pos previewWindow-pos(); if (pos.x() 0) pos.setX(0); if (pos.y() 0) pos.setY(0); previewWindow-move(pos); previewWindow-show(); }我们调整预览窗口的位置这样做的原因是在某些平台上摆弄窗户的框架可能会导致窗户的位置在背后发生变化。如果窗口位于屏幕的左上角则可能看不到该窗口的某些部分。因此我们调整小部件的位置以确保如果发生这种情况窗口在屏幕边界内移动最后调用 QWidget::show() 来确保预览窗口可见。void ControllerWindow::createTypeGroupBox() { typeGroupBox new QGroupBox(tr(Type)); windowRadioButton createRadioButton(tr(Window)); dialogRadioButton createRadioButton(tr(Dialog)); sheetRadioButton createRadioButton(tr(Sheet)); drawerRadioButton createRadioButton(tr(Drawer)); popupRadioButton createRadioButton(tr(Popup)); toolRadioButton createRadioButton(tr(Tool)); toolTipRadioButton createRadioButton(tr(Tooltip)); splashScreenRadioButton createRadioButton(tr(Splash screen)); windowRadioButton-setChecked(true); QGridLayout *layout new QGridLayout; layout-addWidget(windowRadioButton, 0, 0); layout-addWidget(dialogRadioButton, 1, 0); layout-addWidget(sheetRadioButton, 2, 0); layout-addWidget(drawerRadioButton, 3, 0); layout-addWidget(popupRadioButton, 0, 1); layout-addWidget(toolRadioButton, 1, 1); layout-addWidget(toolTipRadioButton, 2, 1); layout-addWidget(splashScreenRadioButton, 3, 1); typeGroupBox-setLayout(layout); }私有的createTypeGroupBox()函数从构造函数中调用。首先我们创建一个组框然后为窗口标志中的每个可用类型创建一个单选按钮使用私有的createRadioButton() 函数我们将Qt::Window作为最初应用的类型将单选按钮放入QGridLayout中并将布局安装在组框上。我们不包含默认的Qt::Widget类型原因是它的行为与其他类型有些不同。如果没有为小部件指定类型并且它没有父部件则该小部件是窗口。但是如果它有父部件它就是标准的子部件。其他类型都是顶级窗口由于提示只影响顶级窗口我们放弃Qt::Widget类型。void ControllerWindow::createHintsGroupBox() { hintsGroupBox new QGroupBox(tr(Hints)); msWindowsFixedSizeDialogCheckBox createCheckBox(tr(MS Windows fixed size dialog)); x11BypassWindowManagerCheckBox createCheckBox(tr(X11 bypass window manager)); framelessWindowCheckBox createCheckBox(tr(Frameless window)); windowNoShadowCheckBox createCheckBox(tr(No drop shadow)); windowTitleCheckBox createCheckBox(tr(Window title)); windowSystemMenuCheckBox createCheckBox(tr(Window system menu)); windowMinimizeButtonCheckBox createCheckBox(tr(Window minimize button)); windowMaximizeButtonCheckBox createCheckBox(tr(Window maximize button)); windowCloseButtonCheckBox createCheckBox(tr(Window close button)); windowContextHelpButtonCheckBox createCheckBox(tr(Window context help button)); windowShadeButtonCheckBox createCheckBox(tr(Window shade button)); windowStaysOnTopCheckBox createCheckBox(tr(Window stays on top)); windowStaysOnBottomCheckBox createCheckBox(tr(Window stays on bottom)); customizeWindowHintCheckBox createCheckBox(tr(Customize window)); QGridLayout *layout new QGridLayout; layout-addWidget(msWindowsFixedSizeDialogCheckBox, 0, 0); layout-addWidget(x11BypassWindowManagerCheckBox, 1, 0); layout-addWidget(framelessWindowCheckBox, 2, 0); layout-addWidget(windowNoShadowCheckBox, 3, 0); layout-addWidget(windowTitleCheckBox, 4, 0); layout-addWidget(windowSystemMenuCheckBox, 5, 0); layout-addWidget(customizeWindowHintCheckBox, 6, 0); layout-addWidget(windowMinimizeButtonCheckBox, 0, 1); layout-addWidget(windowMaximizeButtonCheckBox, 1, 1); layout-addWidget(windowCloseButtonCheckBox, 2, 1); layout-addWidget(windowContextHelpButtonCheckBox, 3, 1); layout-addWidget(windowShadeButtonCheckBox, 4, 1); layout-addWidget(windowStaysOnTopCheckBox, 5, 1); layout-addWidget(windowStaysOnBottomCheckBox, 6, 1); hintsGroupBox-setLayout(layout); }私有的createHintsGroupBox()函数也从构造函数中调用。同样我们要做的第一件事是创建一个组框然后使用私有的createCheckBox()函数为窗口标志中的每个可用提示创建一个复选框。我们将复选框放入QGridLayout中并在组框上安装布局。QCheckBox *ControllerWindow::createCheckBox(const QString text) { QCheckBox *checkBox new QCheckBox(text); connect(checkBox, QCheckBox::clicked, this, ControllerWindow::updatePreview); return checkBox; }私有的createCheckBox()函数从createHintsGroupBox()调用。我们只需用提供的文本创建一个QCheckBox将其连接到私有的updatePreview()槽并返回一个指向复选框的指针。QRadioButton *ControllerWindow::createRadioButton(const QString text) { QRadioButton *button new QRadioButton(text); connect(button, QRadioButton::clicked, this, ControllerWindow::updatePreview); return button; }在私有的createRadioButton()函数中它是我们用提供的文本创建的QRadioButton并连接到私有的updatePreview()槽。该函数从createTypeGroupBox()调用并返回一个指向按钮的指针。未完待续精彩下期继续......