(6)先来个简单的举例,以了解 QDockWidget 的使用 :
++ 熟悉下 QDockWidget 的属性 :
++根据这个麻雀虽小五脏俱全 的例子,阅读与学习 其 ui_widget . h ,以学习和熟悉 QDockWidget 的使用 :
#ifndef UI_MAINWINDOW_H
#define UI_MAINWINDOW_H
#include <QtCore/QVariant>
#include <QtGui/QAction>
#include <QtWidgets/QApplication>
#include <QtWidgets/QDockWidget>
#include <QtWidgets/QHBoxLayout>
#include <QtWidgets/QLineEdit>
#include <QtWidgets/QMainWindow>
#include <QtWidgets/QMenu>
#include <QtWidgets/QMenuBar>
#include <QtWidgets/QPushButton>
#include <QtWidgets/QStatusBar>
#include <QtWidgets/QToolBar>
#include <QtWidgets/QVBoxLayout>
#include <QtWidgets/QWidget>
QT_BEGIN_NAMESPACE
class Ui_MainWindow
{
public:
QAction * actionTime;
QWidget * centralwidget; //主窗体采用了垂直布局
QVBoxLayout * verticalLayout;
QLineEdit * lineEdit;
QMenuBar * menubar;
QMenu * menu;
QStatusBar * statusbar;
QToolBar * toolBar;
QDockWidget * dockWidget; //QDockWidget 采用了水平布局
QWidget * dockWidgetContents;
QHBoxLayout * horizontalLayout;
QPushButton * pushButton;
void setupUi(QMainWindow *MainWindow)
{
if (MainWindow->objectName().isEmpty())
MainWindow->setObjectName(QString::fromUtf8("MainWindow"));
MainWindow->resize(284, 136); //以上是主窗体的设置
actionTime = new QAction(MainWindow); //完善 QAction,并为之添加图片
actionTime->setObjectName(QString::fromUtf8("actionTime"));
QIcon icon;
icon.addFile(QString::fromUtf8(":/icons/images/322.bmp"),
QSize(), QIcon::Normal, QIcon::Off);
actionTime->setIcon(icon);
actionTime->setMenuRole(QAction::NoRole);
centralwidget = new QWidget(MainWindow); //为本程序生成中心窗体,并设置为垂直布局
centralwidget->setObjectName(QString::fromUtf8("centralwidget"));
verticalLayout = new QVBoxLayout(centralwidget);
verticalLayout->setObjectName(QString::fromUtf8("verticalLayout"));
lineEdit = new QLineEdit(centralwidget); //为中心窗体添加行输入框
lineEdit->setObjectName(QString::fromUtf8("lineEdit"));
verticalLayout->addWidget(lineEdit);
MainWindow->setCentralWidget(centralwidget); //本程序接收主窗体
menu = new QMenu(menubar); //生成菜单并添加一个菜单项
menu->setObjectName(QString::fromUtf8("menu"));
menu->addAction(actionTime);
menubar = new QMenuBar(MainWindow); //生成菜单栏并接收上面的菜单
menubar->setObjectName(QString::fromUtf8("menubar"));
menubar->setGeometry(QRect(0, 0, 284, 18));
menubar->addAction( menu->menuAction() );
MainWindow->setMenuBar(menubar); //为程序添加菜单栏
statusbar = new QStatusBar(MainWindow); //为程序生成状态栏
statusbar->setObjectName(QString::fromUtf8("statusbar"));
MainWindow->setStatusBar(statusbar);
toolBar = new QToolBar(MainWindow); //生成工具栏并添加一个按钮
toolBar->setObjectName(QString::fromUtf8("toolBar"));
toolBar->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
toolBar->addAction(actionTime);
MainWindow->addToolBar(Qt::TopToolBarArea, toolBar); //程序接收工具栏
dockWidget = new QDockWidget(MainWindow); //生成码头组件
dockWidget->setObjectName(QString::fromUtf8("dockWidget"));
dockWidget->setFloating(true);
dockWidgetContents = new QWidget(); //为码头组件生成具有水平布局的中心窗体
dockWidgetContents->setObjectName(QString::fromUtf8("dockWidgetContents"));
horizontalLayout = new QHBoxLayout(dockWidgetContents);
horizontalLayout->setObjectName(QString::fromUtf8("horizontalLayout"));
pushButton = new QPushButton(dockWidgetContents); //码头组件里的内容窗体添加按钮
pushButton->setObjectName(QString::fromUtf8("pushButton"));
horizontalLayout->addWidget(pushButton);
dockWidget->setWidget(dockWidgetContents); //码头组件接收其内容窗体
MainWindow->addDockWidget(Qt::LeftDockWidgetArea, dockWidget); //程序接收码头组件,放在左边
retranslateUi(MainWindow);
QMetaObject::connectSlotsByName(MainWindow);
} // setupUi
void retranslateUi(QMainWindow *MainWindow)
{
MainWindow->setWindowTitle(QCoreApplication::translate("MainWindow", "MainWindow", nullptr));
toolBar ->setWindowTitle(QCoreApplication::translate("MainWindow", "toolBar" , nullptr));
dockWidget->setWindowTitle(QCoreApplication::translate("MainWindow", "DockW" , nullptr));
actionTime->setText (QCoreApplication::translate("MainWindow",
"\346\227\266\351\227\264", nullptr));
actionTime->setToolTip (QCoreApplication::translate("MainWindow",
"\346\217\220\347\244\272\346\227\266\351\227\264", nullptr));
actionTime->setShortcut(QCoreApplication::translate("MainWindow", "Ctrl+D", nullptr));
lineEdit ->setPlaceholderText(QCoreApplication::translate("MainWindow",
"\350\277\231\351\207\214\344\274\232\346\230\276"
"\347\244\272\346\227\266\351\227\264", nullptr));
menu ->setTitle(QCoreApplication::translate("MainWindow",
"\350\217\234\345\215\225\346\240\217", nullptr));
pushButton->setText (QCoreApplication::translate("MainWindow", "PushButton", nullptr));
} // retranslateUi
};
namespace Ui {
class MainWindow: public Ui_MainWindow {};
} // namespace Ui
QT_END_NAMESPACE
#endif // UI_MAINWINDOW_H
++
(7)以下开始本类的学习,举例,都要依据完整的程序作为素材,还是以上面的小程序为例:
++
++
(8)以下继续信号函数的学习与整理 :
++
++
++上面的信号函数的测试如下 :
(9) 本源代码来自于头文件 qdockwidget . h :
#ifndef QDYNAMICDOCKWIDGET_H
#define QDYNAMICDOCKWIDGET_H
#include <QtWidgets/qtwidgetsglobal.h>
#include <QtWidgets/qwidget.h>
QT_REQUIRE_CONFIG(dockwidget);
QT_BEGIN_NAMESPACE
class QDockAreaLayout;
class QDockWidgetPrivate;
class QMainWindow;
class QStyleOptionDockWidget;
/*
The QDockWidget class provides a widget that can be docked inside a
QMainWindow or floated as a top-level window on the desktop.
QDockWidget提供了dock widget的概念,也称为工具面板或实用程序窗口。
dock窗口是放置在dock widget区域中的次要窗口,该区域位于QMainWindow中心widget周围。
Dock窗口可以由终端用户在其当前区域内移动,移动到新区域并浮动(例如,未停)。
QDockWidget API允许程序员限制Dock窗口移动、浮动和关闭的能力,以及它们可以放置的区域。
Appearance:
QDockWidget由标题栏和内容区域组成。
标题栏显示dockwidget窗口标题、浮动按钮和关闭按钮。
根据QDockWidget的状态,浮动按钮和关闭按钮可能处于禁用状态或根本未显示。
标题栏和按钮的视觉外观取决于使用的样式。
QDockWidget 充当其子控件的包装器,使用setWidget()对其进行设置。
子控件应实现自定义大小提示、最小和最大大小以及大小策略。
QDockWidget 将尊重这些策略,调整其自身约束以包含框架和标题。
不应在 QDockWidget 本身设置大小约束,因为它们会根据是否停靠而变化;
停靠的 QDockWidget没有框架和较小的标题栏。(可能是标题栏的宽度较小)。
注意:在macOS上,如果QDockWidget具有原生窗口句柄(例如,如果在其上调用winld()或子控件),
则由于限制,在卸载dockwidget时将无法拖动dock widget。
开始拖动将卸载dock widget,但需要第二次拖动才能移动dock widget本身。
*/
class Q_WIDGETS_EXPORT QDockWidget : public QWidget
{
Q_OBJECT
//This property holds the dock widget title (caption)。
//By default, this property contains an empty string.
Q_PROPERTY(QString windowTitle //码头组件的标题
READ windowTitle WRITE setWindowTitle DESIGNABLE true)
//This property holds whether the dock widget is movable, closable, and floatable。
//By default, this property is set to a combination of
// DockWidgetClosable, DockWidgetMovable and DockWidgetFloatable.
Q_PROPERTY(DockWidgetFeatures features //默认可移动、可关闭、可浮动。
READ features WRITE setFeatures
NOTIFY featuresChanged)
//areas where the dock widget may be placed. The default is Qt::AllDockWidgetAreas.
//enum Qt::DockWidgetArea { LeftDockWidgetArea, Right, Top, Bottom, All, No ...};
Q_PROPERTY(Qt::DockWidgetAreas allowedAreas //默认可以停靠于所有区域
READ allowedAreas
WRITE setAllowedAreas
NOTIFY allowedAreasChanged)
Q_PROPERTY(bool floating READ isFloating WRITE setFloating) //默认为 true在浮动
//This property holds whether the dock widget is floating。
//A floating dock widget is presented to the user as an
// independent window "on top" of its parent QMainWindow,
// instead of being docked in the QMainWindow.
//By default, this property is true.
//When this property changes, the topLevelChanged() signal is emitted.
private:
Q_DECLARE_PRIVATE(QDockWidget)
Q_DISABLE_COPY(QDockWidget)
Q_PRIVATE_SLOT(d_func(), void _q_toggleView(bool))
Q_PRIVATE_SLOT(d_func(), void _q_toggleTopLevel())
friend class QDockAreaLayout;
friend class QDockWidgetItem;
friend class QMainWindowLayout;
friend class QDockWidgetLayout;
friend class QDockAreaLayoutInfo;
public:
//Constructs a QDockWidget with parent parent and window flags flags.
//The dock widget will be placed in the left dock widget area.
//The window title is set to title.
//This title is used when the QDockWidget is docked and undocked.
//It is also used in the context menu provided by QMainWindow. //标题用于右键菜单里
explicit QDockWidget(const QString & title,
QWidget * parent = nullptr,
Qt::WindowFlags flags = Qt::WindowFlags()); //窗体类型
explicit QDockWidget(QWidget * parent = nullptr,
Qt::WindowFlags flags = Qt::WindowFlags()); //默认放左边
//Constructs a QDockWidget with parent parent and window flags flags.
//The dock widget will be placed in the left dock widget area.
~QDockWidget();
// Q_PROPERTY(QString windowTitle //码头组件的标题。这是 QWidget本有的属性
// READ windowTitle WRITE setWindowTitle DESIGNABLE true)
enum DockWidgetFeature {
NoDockWidgetFeatures = 0x00,
DockWidgetClosable = 0x01,
DockWidgetMovable = 0x02,
DockWidgetFloatable = 0x04,
DockWidgetVerticalTitleBar = 0x08, //dock 控件在其左侧显示一个垂直的标题栏。
//这可以用于增加 OMainWindow中的垂直空间量。
DockWidgetFeatureMask = 0x0f,
Reserved = 0xff
};
Q_DECLARE_FLAGS(DockWidgetFeatures, DockWidgetFeature)
Q_FLAG( DockWidgetFeatures )
// Q_PROPERTY(DockWidgetFeatures features //默认可移动、可关闭、可浮动。
// READ features WRITE setFeatures
// NOTIFY featuresChanged)
DockWidgetFeatures features() const;
void setFeatures(DockWidgetFeatures features);
// Q_PROPERTY(Qt::DockWidgetAreas allowedAreas //默认可以停靠于所有区域
// READ allowedAreas
// WRITE setAllowedAreas
// NOTIFY allowedAreasChanged)
Qt::DockWidgetAreas allowedAreas() const;
void setAllowedAreas(Qt::DockWidgetAreas areas);
Q_SIGNALS:
void allowedAreasChanged(
Qt::DockWidgetAreas allowedAreas);
public :
// Q_PROPERTY(bool floating
// READ isFloating WRITE setFloating) //默认为 true在浮动
inline bool isFloating() const { return isWindow(); }
void setFloating(bool floating);
//Returns the widget for the dock widget.
//This function returns zero if the widget has not been set.
QWidget * widget() const; //返回码头组件的内容窗体的地址
void setWidget (QWidget * widget);
//Sets the widget for the dock widget to widget.
//If the dock widget is visible when widget is added, you must show() it explicitly.
//Note that you must add the layout of the widget before you call this function;
// if not, the widget will not be visible.
//Returns the custom title bar widget set on the QDockWidget,
// or nullptr if no custom title bar has been set。
QWidget * titleBarWidget() const; //返回码头组件里的自定义标题栏,或 nullptr。
void setTitleBarWidget(QWidget * widget);
//将任意小部件设置为dock小部件的标题栏。
//如果小部件为nullptr,则之前设置在dock小部件上的任何自定义标题栏小部件都将被移除,但不会删除,
// 并且将使用默认的标题栏。
//如果设置了标题栏小部件,则QDockWidget在浮动时不会使用本地窗口装饰。
//Here are some tips for implementing custom title bars:
//(1)标题栏小部件没有明确处理的鼠标事件必须通过调用QMouseEvent::ignore()来忽略这些事件;
// 然后传播到QDockWidget父窗口,后者以通常的方式处理它们,
// 当标题栏。被拖动时移动,双击时停靠和卸载等。
//(2)当将 DockWidgetVerticalTitleBar 设置在 ODockWidget 上时,
// 标题栏控件将相应地进行重新定位。在resizeEvent()中,标题栏应检查应采用哪种方向:
// QDockWidget *dockWidget = qobject_cast<QDockWidget*>(parentWidget());
// if (dockWidget->features() & QDockWidget::DockWidgetVerticalTitleBar) {
// I need to be vertical
// } else {
// I need to be horizontal
// }
//(3)标题栏小部件必须具有有效的QWidget::sizeHint()和QWidget::minimumSizeHint()函数。
// 这些函数应该考虑到标题栏的当前方向。
//(4)无法从dock小部件中移除标题栏。
// 但是,可以通过将默认构造的QWidget设置为标题栏小部件来达到类似的效果。
//使用上面所示的qobject_cast()函数,标题栏小部件可以完全访问其父QDockWidget。
//因此,它可以根据用户操作执行停靠和隐藏等操作。
//Returns true if this dock widget can be placed in the given area;
// otherwise returns false.
inline bool isAreaAllowed(Qt::DockWidgetArea area) const
{ return (allowedAreas() & area) == area; }
//Returns a checkable action that can be added to menus and toolbars so that the
// user can show or close this dock widget.
//The action's text is set to the dock widget's window title.
//Note: The action can not be used to programmatically show or hide the dock widget.
//Use the visible property for that.
QAction * toggleViewAction() const; //这个 QAction可以自动出现在右键菜单里。
//返回一个可检查的操作,可以添加到菜单和工具栏中,以便用户显示或关闭此停靠窗格。
//动作的文本设置为 dock小部件的窗口标题。
//注意:此操作不能用于以编程方式显示或隐藏dock小部件。请使用可见性属性。
Q_SIGNALS:
//This signal is emitted when the features property changes.
//The features parameter gives the new value of the property.
void featuresChanged(QDockWidget::DockWidgetFeatures features );
//void allowedAreasChanged( Qt::DockWidgetAreas allowedAreas); //这是函数
//This signal is emitted when the allowedAreas property changes.
//The allowedAreas parameter gives the new value of the property.
//This signal is emitted when the floating property changes.
//The topLevel parameter is true if the dock widget is now floating;
// otherwise it is false.
void topLevelChanged(bool topLevel); //当浮动起来后,形参为 true。
void visibilityChanged(bool visible );
//This signal is emitted when the dock widget becomes visible (or invisible).
//当小部件被隐藏或显示时,以及当它被停靠在一个标签式dock区域且其标签被选中或未选中时,
// 都会发生这种情况。This happens when the widget is hidden or shown,
//as well as when it is docked in a tabbed dock area ,
// and its tab becomes selected or unselected.
void dockLocationChanged(Qt::DockWidgetArea area);
//This signal is emitted when the dock widget is moved to another dock area,
// or is moved to a different location in its current dock area.
//This happens when the dock widget is moved programmatically,
// or is dragged to a new location by the user.
protected:
bool event(QEvent * event) override;
void changeEvent(QEvent * event) override;
void closeEvent(QCloseEvent * event) override;
void paintEvent(QPaintEvent * event) override;
virtual void initStyleOption(QStyleOptionDockWidget *option) const;
}; //完结 class QDockWidget : public QWidget
Q_DECLARE_OPERATORS_FOR_FLAGS(QDockWidget::DockWidgetFeatures)
QT_END_NAMESPACE
#endif // QDYNAMICDOCKWIDGET_H
(10)
谢谢