Qt容器组件(二)之QWidgetStack、QMdiArea、QDockWidget
QT中有九种容器组件,分别是组合框QGroupBox、滚动区QScrollArea、工具箱QToolBox、选项卡QTabWidget、控件栈QWidgetStack、框架QFrame、组件QWidget、MDI窗口显示区QMdiArea、停靠窗口QDockWidget。
本博主要介绍:组合框QGroupBox、滚动区QScrollArea、工具箱QToolBox、选项卡QTabWidget
一、控件栈QWidgetStack
(1)属性
class Q_WIDGETS_EXPORT QStackedWidget : public QFrame { Q_OBJECT Q_PROPERTY(int currentIndex READ currentIndex WRITE setCurrentIndex NOTIFY currentChanged) Q_PROPERTY(int count READ count) 。。。。。。。。。。。。。。。 }
(2)常用函数
int addWidget(QWidget *w); int insertWidget(int index, QWidget *w); void removeWidget(QWidget *w); QWidget *currentWidget() const; int currentIndex() const; int indexOf(QWidget *) const; QWidget *widget(int) const; int count() const;
(3)信号、槽
public Q_SLOTS: void setCurrentIndex(int index); void setCurrentWidget(QWidget *w); Q_SIGNALS: void currentChanged(int); void widgetRemoved(int index);
(4)示例
#include "mainwindow.h" #include <QApplication> #include <QListWidget> #include <QHBoxLayout> #include <QLabel> #include <QStackedWidget> #include <QObject> int main(int argc, char *argv[]) { QApplication a(argc, argv); MainWindow w; QWidget *pWidget = new QWidget(&w); QHBoxLayout *pLayout = new QHBoxLayout(pWidget); QStackedWidget *pStackedWidget = new QStackedWidget(pWidget); QListWidget* pList = new QListWidget(pWidget); pList->insertItem(0, "label0"); pList->insertItem(1, "label1"); pList->insertItem(2, "label2"); QLabel* pLabel0 = new QLabel("label0 test"); QLabel* pLabel1 = new QLabel("label1 test"); QLabel* pLabel2 = new QLabel("label2 test"); pStackedWidget->addWidget(pLabel0); pStackedWidget->addWidget(pLabel1); pStackedWidget->addWidget(pLabel2); w.connect(pList, SIGNAL(currentRowChanged(int)), pStackedWidget, SLOT(setCurrentIndex(int))); pLayout->addWidget(pList); pLayout->addWidget(pStackedWidget,0,Qt::AlignCenter); pLayout->setStretchFactor(pList, 1); pLayout->setStretchFactor(pStackedWidget, 3); pWidget->setLayout(pLayout); w.setCentralWidget(pWidget); w.setWindowTitle("container test"); w.setMinimumSize(50,50); w.show(); return a.exec(); }
二、QMdiArea多文档区域组件
QMdiArea组件中文称作“MDI窗口显示区”,MDI是 Multiple Document Interface的简称,中文意思是多文档界面,主要适用于完成一项工作时需要用到多个文件。QMainWindow是SDI(Signal Document Interface,单文档界面)每个开启的文件占据一个视窗,主要适用于所有工作没有太多文件参与的情况。
QMdiSubWindow类继承自QWidget,主要用来创建MDI子窗体实例
QtExmaple中提供了相应的例子:\Examples\Qt-5.9.3\widgets\mainwindows\mdi
(1)属性
背景、窗口顺序(SubWindowList)、视图模式(SubWindowView/tabbedView)、tabsClosable、tabsMovable、TabPositionTabShape
class Q_WIDGETS_EXPORT QMdiArea : public QAbstractScrollArea { Q_OBJECT Q_PROPERTY(QBrush background READ background WRITE setBackground) Q_PROPERTY(WindowOrder activationOrder READ activationOrder WRITE setActivationOrder) Q_PROPERTY(ViewMode viewMode READ viewMode WRITE setViewMode) #if QT_CONFIG(tabbar) Q_PROPERTY(bool documentMode READ documentMode WRITE setDocumentMode) Q_PROPERTY(bool tabsClosable READ tabsClosable WRITE setTabsClosable) Q_PROPERTY(bool tabsMovable READ tabsMovable WRITE setTabsMovable) #endif #if QT_CONFIG(tabwidget) Q_PROPERTY(QTabWidget::TabShape tabShape READ tabShape WRITE setTabShape) Q_PROPERTY(QTabWidget::TabPosition tabPosition READ tabPosition WRITE setTabPosition) 。。。。。。。。。。。 }
(2)常用函数、信号、槽
QSize sizeHint() const Q_DECL_OVERRIDE; QSize minimumSizeHint() const Q_DECL_OVERRIDE; QMdiSubWindow *currentSubWindow() const; QMdiSubWindow *activeSubWindow() const; QList<QMdiSubWindow *> subWindowList(WindowOrder order = CreationOrder) const; QMdiSubWindow *addSubWindow(QWidget *widget, Qt::WindowFlags flags = Qt::WindowFlags()); void removeSubWindow(QWidget *widget); QBrush background() const; void setBackground(const QBrush &background); WindowOrder activationOrder() const; void setActivationOrder(WindowOrder order); void setOption(AreaOption option, bool on = true); bool testOption(AreaOption opton) const; void setViewMode(ViewMode mode); ViewMode viewMode() const;
Q_SIGNALS: void subWindowActivated(QMdiSubWindow *); public Q_SLOTS: void setActiveSubWindow(QMdiSubWindow *window); void tileSubWindows(); void cascadeSubWindows(); void closeActiveSubWindow(); void closeAllSubWindows(); void activateNextSubWindow(); void activatePreviousSubWindow(); protected Q_SLOTS: void setupViewport(QWidget *viewport) Q_DECL_OVERRIDE;
(3)示例
:\Examples\Qt-5.9.3\widgets\mainwindows\mdi
(4)注意Mdi子窗口的关闭
void MainWindow::closeEvent(QCloseEvent *event) { m_pMdiArea->closeAllSubWindows(); if (m_pMdiArea->currentSubWindow()) { event->ignore(); } else { event->accept(); } }
三、QDockWidget停靠窗口
QDockWidget停靠窗体组件,可以作为一个顶层窗口漂浮在桌面,主要作为辅助窗体出现在界面中,可以在很多IDE中看到停靠窗体。
QDockWidget包含工具栏和内容区域,工具栏用于显示窗口标题,一个浮动按钮和一个关闭按钮。QDockWidget可以作为子窗口部件的封装,通过setWidget()设置子窗口部件。自定义的尺寸提示,最小和最大化尺寸以及尺寸策略都必须由子窗口部件来实现。QDockWidget会遵守它们,调整它自己的限制包括框架和工具栏。我们不应该为QDockWidget设置尺寸限制,因为它们根据QDockWidget是否锁住而改变,一个锁住的QDockWidget窗口部件不 包括框架和小的工具栏。
(1)属性
属性包括:是否悬浮、停靠窗口特征(移动,关闭,悬浮)、停靠区域、窗口标题
class Q_WIDGETS_EXPORT QDockWidget : public QWidget { Q_OBJECT Q_PROPERTY(bool floating READ isFloating WRITE setFloating) Q_PROPERTY(DockWidgetFeatures features READ features WRITE setFeatures NOTIFY featuresChanged) Q_PROPERTY(Qt::DockWidgetAreas allowedAreas READ allowedAreas WRITE setAllowedAreas NOTIFY allowedAreasChanged) Q_PROPERTY(QString windowTitle READ windowTitle WRITE setWindowTitle DESIGNABLE true) 。。。。。。。。。。。。。。。。。 }
窗口特征枚举:
enum DockWidgetFeature { DockWidgetClosable = 0x01, DockWidgetMovable = 0x02, DockWidgetFloatable = 0x04, DockWidgetVerticalTitleBar = 0x08, DockWidgetFeatureMask = 0x0f, AllDockWidgetFeatures = DockWidgetClosable|DockWidgetMovable|DockWidgetFloatable, // ### Qt 6: remove NoDockWidgetFeatures = 0x00, Reserved = 0xff };
(2)信号、槽
Q_SIGNALS: void featuresChanged(QDockWidget::DockWidgetFeatures features); void topLevelChanged(bool topLevel); void allowedAreasChanged(Qt::DockWidgetAreas allowedAreas); void visibilityChanged(bool visible); void dockLocationChanged(Qt::DockWidgetArea area); protected: void changeEvent(QEvent *event) Q_DECL_OVERRIDE; void closeEvent(QCloseEvent *event) Q_DECL_OVERRIDE; void paintEvent(QPaintEvent *event) Q_DECL_OVERRIDE; bool event(QEvent *event) Q_DECL_OVERRIDE; void initStyleOption(QStyleOptionDockWidget *option) const;
(3)示例
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) //ui(new Ui::MainWindow) { setWindowTitle("MDI test"); setMinimumSize(400,400); m_pFileAction = new QAction("open", this); m_pFileMenu = menuBar()->addMenu("File"); m_pFileMenu->addAction(m_pFileAction); connect(m_pFileAction, SIGNAL(triggered(bool)), this, SLOT(openView())); m_pMdiArea = new QMdiArea(this); m_pMdiArea->setViewMode(QMdiArea::TabbedView); m_pMdiArea->setTabShape(QTabWidget::Triangular); m_pMdiArea->setTabPosition(QTabWidget::North); m_pMdiArea->setTabsMovable(true); m_pMdiArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded); m_pMdiArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); setCentralWidget(m_pMdiArea); QDockWidget* pDockWidget = new QDockWidget("dockwindow", this); pDockWidget->setFeatures(QDockWidget::DockWidgetFeature::AllDockWidgetFeatures); QWidget* pWidget = new QWidget(this); QVBoxLayout *pLayout = new QVBoxLayout(pWidget); QPushButton *pOkBtn = new QPushButton("ok"); QPushButton *pCancelBtn = new QPushButton("cancel"); pLayout->addWidget(pOkBtn); pLayout->addWidget(pCancelBtn); pDockWidget->setWidget(pWidget); addDockWidget(Qt::DockWidgetArea::RightDockWidgetArea, pDockWidget); }