(4)关于本类的测试并不容易,而且老师也没有教学 dock widget 的使用,无心进行完善的整理。关于本类的使用与测试,可参考这篇文章
(5)本源代码来自于头文件 qmainwindow . h :
#ifndef QDYNAMICMAINWINDOW_H
#define QDYNAMICMAINWINDOW_H
#include <QtWidgets/qtwidgetsglobal.h>
#include <QtWidgets/qwidget.h>
#if QT_CONFIG(tabwidget)
#include <QtWidgets/qtabwidget.h>
#endif
QT_REQUIRE_CONFIG(mainwindow);
QT_BEGIN_NAMESPACE
class QDockWidget;
class QMainWindowPrivate;
class QMenuBar;
class QStatusBar;
class QToolBar;
class QMenu;
/*
The QMainWindow class provides a main application window.
主窗口提供了构建应用程序用户界面的框架。Qt有用于主窗口管理的QMainWindow及其相关类。
QMainWindow有自己的布局,您可以在其中添加QToolBar、QDockWidget、QMenuBar和QStatusBar。
布局有一个中心区域,任何类型的小部件都可以占用。
注意:不支持创建没有中央小部件的主窗口。即使只是一个占位符,也必须有一个中央小部件。
Creating Main Window Components :
中央小部件通常是一个标准的Qt小部件,如QTextEdit或QGraphicsView。自定义小部件也可以用于高级应用程序。
您可以使用setCentralWidget()设置中央小部件。
主窗口具有单个(SDI)或多个(MDI)文档界面。您可以通过使用QMdiArea作为中心小部件在Qt中创建MDI应用程序。
我们现在将检查可以添加到主窗口的每个其他小部件。我们给出如何创建和添加它们的示例。
Creating Menus:
Qt 在 QMenu 中实现菜单,QMainWindow 将它们保存在 QMenuBar 中。
QActions 被添加到菜单中,它们以菜单项的形式显示。
您可以通过调用menuBar()来将新菜单添加到主窗口的菜单栏中,
该函数返回窗口的QMenuBar,然后使用QMenuBar::addMenu()添加菜单。
QMainWindow 带有默认的菜单栏,但您也可以使用setMenuBar()自定义菜单栏。
如果您想实现自定义菜单栏(即不使用 QMenuBar组件),可以使用 setMenuWidget()来设置。
An example of how to create menus follows:
void MainWindow::createMenus()
{
fileMenu = menuBar()->addMenu(tr("&File"));
fileMenu->addAction(newAct );
fileMenu->addAction(openAct);
fileMenu->addAction(saveAct);
当主窗口接收到上下文菜单事件时,createPopupMenu()函数会创建弹出菜单。
默认实现会从dock小部件和工具栏生成带有可检查操作项的菜单。
您可以为自定义菜单重新实现createPopupMenu()函数。
Creating Toolbars :
工具栏在 QToolBar 类中实现。您可以使用 addToolBar()方法将工具栏添加到主窗口中。
您可以通过将工具栏分配到特定的Qt:ToolBarArea来控制它们的初始位置。
您可以使用addToolBarBreak()或insertToolBarBreak()通过插入一个工具栏换行符来分割区域.
这在文本编辑中被认为是换行符。
您还可以使用QToolBar:setAllowedArea()和QToolBar.:setMovable()来限制用户的位置。
可以使用iconSize()函数检索工具栏图标的尺寸。尺寸取决于平台;您可以使用setIconSize()函数设置固定尺寸。
您可以使用setToolButtonStyle()函数更改工具栏中所有工具按钮的外观。
创建工具栏的示例如下:
void MainWindow::createToolBars()
{
fileToolBar = addToolBar(tr("File"));
fileToolBar->addAction(newAct);
Creating Dock Widgets:
Dock小部件在QDockWidget类中实现。Dock小部件是可以停靠到主窗口中的窗口。
您可以通过addDockWidget()将Dock小部件添加到主窗口中。
根据Qt::DockWidgetArea枚举,有四个dock小部件区域:左、右、上、下。
您可以通过setCorner指定哪个dock小部件区域应占据重叠区域。
默认情况下,每个区域只能包含一行(垂直或水平)dock小部件,
但通过setDockNestingEnabled()启用嵌套后,dock小部件可以以任何方向添加。
两个dock小部件也可以堆叠在一起。然后使用QTabBar来选择应该显示哪些小部件。
我们给出一个如何在主窗口中创建和添加dock小部件的示例:
QDockWidget * dockWidget = new QDockWidget(tr("Dock Widget"), this);//创建 QDockWidget
dockWidget->setAllowedAreas(Qt::LeftDockWidgetArea | //给其指定停靠区域
Qt::RightDockWidgetArea);
dockWidget->setWidget(dockWidgetContents); //为其指定中心窗体
addDockWidget(Qt::LeftDockWidgetArea, dockWidget); //把 QDockWidget添加到主窗体界面
The Status Bar :
您可以使用 setStatusBar()函数设置状态栏,但第一次调用 statusBar()时就会创建状态栏。
有关如何使用它的信息,请参QStatusBar。(返回主窗口的状态栏)
Storing State :
QMainWindow 可以通过 saveState()函数存储其布局的状态;之后可以通过restoreState()函数检索它。
它是存储的工具栏和停靠窗格的位置和大小(相对于主窗口的大小)。
*/
class Q_WIDGETS_EXPORT QMainWindow : public QWidget //先暂时略去 dock widget的学习
{
Q_OBJECT
//主窗口中工具栏图标的尺寸。 默认值是 GUI样式默认的工具栏图标大小。
//请注意,使用的图标必须至少是这个大小,因为图标只会缩小。
Q_PROPERTY(QSize iconSize //工具栏也有此属性
READ iconSize WRITE setIconSize)
Q_PROPERTY(Qt::ToolButtonStyle toolButtonStyle //工具栏的同名属性会覆盖本属性
READ toolButtonStyle WRITE setToolButtonStyle)
//在该主窗口中设置工具栏按钮的样式。
//要使工具按钮的样式遵循系统设置,请将此属性设置为Qt::ToolButtonFollowStyle。
//在Unix上将使用来自桌面环境的用户设置。在其他平台上,Qt:ToolButtonFollowStyle表示仅图标。
//默认值是 Ot::ToolButtonlconOnly。
//有定义 QT_CONFIG(dockwidget)、QT_CONFIG(tabbar)、QT_CONFIG(tabwidget)、QT_CONFIG(menu)
//这个属性表示是否对停靠小部件和工具栏进行动画处理.。
//当一个停靠窗格或工具栏被拖到主窗口上时,主窗口会调整其内容,
// 以指示如果停靠窗格或工具栏被放下,它将停靠的位置。
//设置此属性会导致QMainWindow以平滑动画移动其内容。清除此属性会导致内容快速定位到其新位置。
//默认情况下,此属性已设置。
//如果主窗口包含在调整大小或重新绘制自身时速度较慢的控件,则可能会清除此属性。
//设置此属性与使用 setDockOptions()函数设置 AnimatedDocks 选项相同。
Q_PROPERTY(bool animated READ isAnimated WRITE setAnimated) //过渡动画的意思
//This property holds whether the
// tab bar for tabbed dockwidgets is set to document mode.The default is false.
Q_PROPERTY(bool documentMode //只研究简单的码头组件即可,老师还没讲 tab功能
READ documentMode WRITE setDocumentMode)
//This enum type defines the shape of the tabs。
//enum QTabWidget::TabShape { Rounded, Triangular };
Q_PROPERTY(QTabWidget::TabShape tabShape READ tabShape WRITE setTabShape)
//This property holds the tab shape used for tabbed dock widgets.
//The default is QTabWidget::Rounded.
//此属性表示码头是否可以嵌套。如果此属性为假,则停靠区域只能包含一行(水平或垂直)的停靠小部件。
//如果此属性为真,则停靠小部件占用的区域可以沿任何方向分割以包含更多停靠小部件。
//在包含大量 Dock 小部件的应用程序中,Dock 嵌套是必要的。它为用户组织主窗口提供了更大的自由度。
//然而,当 Dock 小部件被拖到主窗口上时,Dock 嵌套会导致更复杂(且不那么直观)的行为,
// 因为 Dock小部件可以以更多方式放置在 Dock 区域中。
//设置此属性与使用 setDockOptions()设置 AllowNestedDocks 选项相同。
Q_PROPERTY(bool dockNestingEnabled //暂时不研究此复杂清醒
READ isDockNestingEnabled WRITE setDockNestingEnabled)
Q_PROPERTY(DockOptions dockOptions //默认码头组件具有动画和 tab属性
READ dockOptions WRITE setDockOptions)
//This property holds the docking behavior of QMainWindow。
//The default value is AnimatedDocks | AllowTabbedDocks.
Q_PROPERTY(bool unifiedTitleAndToolBarOnMac
READ unifiedTitleAndToolBarOnMac
WRITE setUnifiedTitleAndToolBarOnMac)
//此属性表示窗口是否在 macOs 上使用统一的标题栏和工具栏外观。
//请注意,与Qt4相比,Qt5的实现存在一些限制:
//不支持在带有0penGL内容的窗口中使用。这包括Q0penGLWidget。
//使用可停靠或可移动的工具栏可能会导致绘画错误,不建议使用。
public:
//Constructs a QMainWindow with the given parent and the specified widget flags.
//QMainWindow sets the Qt::Window flag itself, //形参2 描述窗体的类型
// and will hence always be created as a top-level widget.
explicit QMainWindow(QWidget * parent = nullptr,
Qt::WindowFlags flags = Qt::WindowFlags());
//enum Qt::WindowType { Widget, Window, Dialog, Popup, SubWindow, ... }
//类型 WindowFlags = QFlags<WindowType>
~QMainWindow();
// Q_PROPERTY(QSize iconSize //工具栏也有此属性
// READ iconSize WRITE setIconSize)
QSize iconSize() const;
void setIconSize(const QSize & iconSize);
// Q_PROPERTY(Qt::ToolButtonStyle toolButtonStyle //工具栏的同名属性会覆盖本属性
// READ toolButtonStyle WRITE setToolButtonStyle)
Qt::ToolButtonStyle toolButtonStyle() const;
void setToolButtonStyle(Qt::ToolButtonStyle toolButtonStyle);
// Q_PROPERTY(bool animated
// READ isAnimated WRITE setAnimated) //过渡动画的意思
bool isAnimated() const;
public Q_SLOTS:
void setAnimated(bool enabled);
public:
// Q_PROPERTY(bool documentMode //又是关于 dock,略
// READ documentMode WRITE setDocumentMode)
bool documentMode() const;
void setDocumentMode(bool enabled);
// Q_PROPERTY(QTabWidget::TabShape tabShape
// READ tabShape WRITE setTabShape)
QTabWidget::TabShape tabShape() const;
void setTabShape(QTabWidget::TabShape tabShape);
QTabWidget::TabPosition tabPosition(Qt::DockWidgetArea area) const;
void setTabPosition(Qt::DockWidgetAreas areas,
QTabWidget::TabPosition tabPosition);
// Q_PROPERTY(bool dockNestingEnabled //暂时不详细学习了,老师没举关于 dock的例子
// READ isDockNestingEnabled WRITE setDockNestingEnabled)
bool isDockNestingEnabled() const;
public Q_SLOTS:
void setDockNestingEnabled(bool enabled);
public:
enum DockOption {
AnimatedDocks = 0x01,
AllowNestedDocks = 0x02,
AllowTabbedDocks = 0x04,
ForceTabbedDocks = 0x08, // implies AllowTabbedDocks, !AllowNestedDocks
VerticalTabs = 0x10, // implies AllowTabbedDocks
GroupedDragging = 0x20 // implies AllowTabbedDocks
};
Q_ENUM( DockOption )
Q_DECLARE_FLAGS(DockOptions, DockOption)
Q_FLAG( DockOptions )
// Q_PROPERTY(DockOptions dockOptions
// READ dockOptions WRITE setDockOptions)
DockOptions dockOptions() const;
void setDockOptions(DockOptions options);
// Q_PROPERTY(bool unifiedTitleAndToolBarOnMac
// READ unifiedTitleAndToolBarOnMac
// WRITE setUnifiedTitleAndToolBarOnMac)
bool unifiedTitleAndToolBarOnMac() const;
public Q_SLOTS:
void setUnifiedTitleAndToolBarOnMac(bool set);
public:
bool isSeparator(const QPoint & pos) const; //无注释
//返回主窗口的菜单栏。如果菜单栏不存在,则此函数创建并返回一个空菜单栏。
//Returns the menu bar for the main window.
//如果您想让 Mac 应用程序中的所有窗口共享一个菜单栏,
//请不要使用此函数来创建它,因为在此处创建的菜单栏将具有此 QMainWindow 作为其父项。
//相反,您必须创建一个没有父项的菜单栏,然后可以在所有 Mac 窗口之间共享。
//通过以下方式创建一个没有父项的菜单栏: QMenuBar * menuBar = new QMenuBar(nullptr);
QMenuBar * menuBar () const;
void setMenuBar (QMenuBar * menubar); //本窗体会成为形参 menubar的父类
//Sets the menu bar for the main window to menuBar.
//Note: QMainWindow takes ownership of the menuBar pointer and
// deletes it at the appropriate time.
//Returns the menu bar for the main window.
//This function returns null if a menu bar hasn't been constructed yet.
QWidget * menuWidget() const; //看注释,返回的还是菜单栏对象
void setMenuWidget(QWidget * menubar);
//Sets the menu bar for the main window to menuBar.
//Inserts the toolbar into the area occupied by the before toolbar ,
// so that it appears before it. //把工具栏 toolbar插入到 before的前面
//For example, in normal left-to-right layout operation,
//this means that toolbar will appear to the left of the
// toolbar specified by before in a horizontal toolbar area.
void insertToolBar(QToolBar * before, QToolBar * toolbar);
void addToolBar(QToolBar * toolbar);
//Equivalent of calling addToolBar(Qt::TopToolBarArea, toolbar)
//Adds the toolbar into the specified area in this main window.
//The toolbar is placed at the end of the current tool bar block (i.e. line).
//If the main window already manages toolbar,
// then it will only move the toolbar to area.
void addToolBar(Qt::ToolBarArea area, QToolBar * toolbar);
QToolBar * addToolBar(const QString & title);
//Creates a QToolBar object, setting its window title to title,
// and inserts it into the top toolbar area.
void removeToolBar(QToolBar * toolbar); //所谓的删除工具栏,只是隐藏而已
//Removes the toolbar from the main window layout and hides it.
//Note that the toolbar is not deleted.
//Inserts a toolbar break before the toolbar specified by before.
void insertToolBarBreak(QToolBar * before); //在形参 before的前面换行
void addToolBarBreak(Qt::ToolBarArea area = Qt::TopToolBarArea);
//Adds a toolbar break to the given area after all the other objects that are present.
void removeToolBarBreak(QToolBar * before); //删除形参 before前面的换行符
//Removes a toolbar break previously inserted before the toolbar specified by before.
//Returns the Qt::ToolBarArea for toolbar.
//If toolbar has not been added to the main window,
//this function returns Qt::NoToolBarArea.
Qt::ToolBarArea toolBarArea (const QToolBar * toolbar) const;
bool toolBarBreak( QToolBar * toolbar) const; //布尔量
//Returns whether there is a toolbar break before the toolbar.
//返回形参 toolBar前面是否有换行符。
//Returns the central widget for the main window.
//This function returns zero if the central widget has not been set.
QWidget * centralWidget() const; //本函数可以返回空值,因为没有为本窗体配备中心窗体、
void setCentralWidget(QWidget * widget);
//Sets the given widget to be the main window's central widget.
//Note: QMainWindow takes ownership of the widget pointer,
// and deletes it at the appropriate time.
QWidget * takeCentralWidget(); //名为 take,其实是删除本窗体具有的中心窗体
//Removes the central widget from this main window.
//The ownership of the removed widget is passed to the caller.
//Returns the status bar for the main window.
//This function creates and returns an empty status bar if the
// status bar does not exist.
QStatusBar * statusBar() const;
void setStatusBar(QStatusBar * statusbar);
//Sets the status bar for the main window to statusbar.
//Setting the status bar to nullptr will remove it from the main window.
//Note that QMainWindow takes ownership of the
// statusbar pointer and deletes it at the appropriate time.
//保存当前主窗口的工具栏和停靠窗格的状态。这包括可以用setCorner()设置的角部设置。
//版本号作为数据的一部分存储。 obiectName 属性用于标识每个 QToolBar和 ODockWidget。
//您应确保为添加到 QMainwindow 中的每个 QToolBar 和 QDOCKWIDGET 设置一个唯一的属性值。
//要恢复保存的状态,请将返回值和版本号传递给restoreState()函数。
QByteArray saveState(int version = 0) const;
bool restoreState(const QByteArray & state, int version = 0);
//Restores the state of this mainwindow's toolbars and dockwidgets.
//Also restores the corner settings too.
//The version number is compared with that stored in state.
//If they do not match, the mainwindow's state is left unchanged,
// and this function returns false;
//otherwise, the state is restored, and this function returns true.
//类型 QByteArray就是 C语言的字符串,并为之定义了完备的成员函数。
bool restoreDockWidget(QDockWidget * dockwidget);
//Restore恢复 the state of dockwidget if it is created after the
// call to restoreState(). Returns true if the state was restored;
// otherwise returns false.
virtual QMenu * createPopupMenu();
//返回一个弹出菜单,其中包含主窗口中工具栏和停靠窗格的可检查条目。
//如果没有工具栏和停靠窗格,此函数返回 nullptr.
//默认情况下,当用户通过右键单击工具栏或停靠窗格来激活上下文菜单时,主窗口会调用此函数。
//如果你想创建一个自定义弹出菜单,请重新实现此函数并返回一个新创建的弹出菜单。
//弹出菜单的所有权将转移到调用者。
//指定哪个DockWidgetArea占据这个角落,左右上下。
//Returns the dock widget area that occupies the specified corner.
Qt::DockWidgetArea corner(Qt::Corner corner) const;
void setCorner(Qt::Corner corner, Qt::DockWidgetArea area);
//Sets the given dock widget area to occupy the specified corner.
//Returns the Qt::DockWidgetArea for dockwidget.
//If dockwidget has not been added to the main window,
// this function returns Qt::NoDockWidgetArea.
Qt::DockWidgetArea dockWidgetArea(QDockWidget * dockwidget) const;
//Adds the given dockwidget to the specified area.
void addDockWidget(Qt::DockWidgetArea area,
QDockWidget * dockwidget);
void addDockWidget(Qt::DockWidgetArea area,
QDockWidget * dockwidget,
Qt::Orientation orientation);
//Adds dockwidget into the given area in the direction specified by the
// orientation.
//Removes the dockwidget from the main window layout and hides it.
//Note that the dockwidget is not deleted. //注释显示被 remove的码头组件没被内存释放
void removeDockWidget(QDockWidget * dockwidget);
void splitDockWidget(QDockWidget * first,
QDockWidget * second,
Qt::Orientation orientation);
//将第一个停靠窗格所覆盖的空间分成两部分,
//将第一个停靠窗格移动到第一部分,将第二个停靠窗格移动到第二部分。
//方向指定空间如何划分:
// Qt::Horizontal拆分将第二个停靠窗格放在第一个的右侧;
// Qt::Vertical拆分将第二个停靠窗格放置在第一个的下方。
//注意:如果第一个选项卡目前位于分页停靠区域,第二个选项卡将作为新选项卡添加,
// 而不是作为第一个选项卡的邻居。这是因为单个选项卡只能包含一个停靠小部件。
//注意:Qt::LayoutDirection 会影响分隔区域两部分中dock小部件的顺序。
//当启用从右到左的布局方向时dock小部件的放置将被反转。
//Moves second dock widget on top of first dock widget,
// creating a tabbed docked area in the main window.
void tabifyDockWidget (QDockWidget * first, //第二个在上面
QDockWidget * second);
QList<QDockWidget *> tabifiedDockWidgets(QDockWidget * dockwidget) const;
//Returns the dock widgets that are tabified together with dockwidget.
void resizeDocks( const QList<QDockWidget *> & docks,
const QList<int> & sizes,
Qt::Orientation orientation);
//将列表停靠窗格中的停靠窗格调整为相应的像素大小。
//如果方向为 Qt::Horizontal,则调整停靠窗格的宽度,否则调整停靠窗格的高度。
//调整大小以确保最大和最小大小得到尊重,且 QMainWindow 本身不会被调整大小。
//任何额外的/缺失的空间将根据大小的相对权重在停靠窗格之间分配。
//举例: resizeDocks( {blueWidget, yellowWidget}, {20 , 40}, Qt::Horizontal );
//如果蓝色和黄色的控件嵌套在同一层,它们将重新调整大小,使黄色控件的大小是蓝色控件的两倍。
//如果某些小部件被分组在选项卡中,则每个组应仅指定一个小部件。
//不在列表中的小部件可能会更改以遵守约束。
public Q_SLOTS: //都是属性的设置函数,注释略
//void setAnimated(bool enabled);
//void setDockNestingEnabled(bool enabled);
//void setUnifiedTitleAndToolBarOnMac(bool set);
Q_SIGNALS:
//This signal is emitted when the size of the icons used in the
// window is changed. The new icon size is passed in iconSize.
//You can connect this signal to other components to help maintain a
// consistent appearance for your application.
void iconSizeChanged(const QSize & iconSize );
void toolButtonStyleChanged(Qt::ToolButtonStyle toolButtonStyle);
//This signal is emitted when the style used for tool buttons in the
// window is changed. The new style is passed in toolButtonStyle.
//You can connect this signal to other components to help maintain a
// consistent appearance for your application.
void tabifiedDockWidgetActivated(QDockWidget * dockWidget);
//This signal is emitted when the //当该组码头控件被激活时触发本信号
// tabified dock widget is activated by selecting the tab.
//The activated dock widget is passed in dockWidget.
protected:
bool event(QEvent * event) override;
void contextMenuEvent(QContextMenuEvent * event) override;
private:
Q_DECLARE_PRIVATE(QMainWindow)
Q_DISABLE_COPY(QMainWindow)
}; //完结 class QMainWindow : public QWidget
Q_DECLARE_OPERATORS_FOR_FLAGS(QMainWindow::DockOptions)
QT_END_NAMESPACE
#endif // QDYNAMICMAINWINDOW_H
(6)
谢谢