Qt学习(六)—— QMainWindow

817 阅读8分钟

菜单栏

菜单栏

要使用菜单栏控件,需要先引入和头文件。创建一个带菜单栏的QMainWindow语句如下:

#include "MainWindow.h"
#include "ui_MainWindow.h"
#include <QMenuBar>
#include <QMenu>
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    QMenuBar *mbar=menuBar();    //注意这里不需要用new关键字
    setMenuBar(mbar);    //写不写都会出现菜单栏,但最好还是写一下
 
}
 
MainWindow::~MainWindow()
{
    delete ui;
}

实现效果如下:

现在,有了装载菜单的菜单栏,我们可以往里添加菜单标签了。

P.S:setMenuBar()写不写在实现效果上都会显示菜单栏,但最好还是写一下,以免出现不必要的错误。

菜单标签

添加菜单要调用QMenuBar对象的addMenu()方法,并用一个QMenu对象指针来接收。

#include "MainWindow.h"
#include "ui_MainWindow.h"
#include <QMenuBar>
#include <QMenu>
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    //菜单栏
    QMenuBar *mbar=menuBar();
    //添加菜单
    QMenu *pFile=mbar->addMenu("文件");
}
 
MainWindow::~MainWindow()
{
    delete ui;
}

现在窗口中出现了一个名为“文件”的菜单标签。

菜单项

正常情况下,我们点击菜单标签应该要弹出一些菜单项,如何实现?

添加菜单项需要调用QMenu对象的addAction方法,并用一个QAction对象指针来接收它。

#include "MainWindow.h"
#include "ui_MainWindow.h"
#include <QMenuBar>
#include <QMenu>
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    //菜单栏
    QMenuBar *mbar=menuBar();
    //添加菜单
    QMenu *pFile=mbar->addMenu("文件");
    //添加菜单项
    QAction *pCreate=pFile->addAction("新建");
}
 
MainWindow::~MainWindow()
{
    delete ui;
}

实现效果:

 

这样我们就实现了一个拥有一个"新建"菜单项的菜单标签了。

分割线

每个菜单标签的菜单项根据功能的不同往往会用分割线来分割,如何实现分割线?

要实现分割线需要用菜单QMenu对象调用addSeperator方法。

#include "MainWindow.h"
#include "ui_MainWindow.h"
#include <QMenuBar>
#include <QMenu>
#include <QDebug>
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    //菜单栏
    QMenuBar *mbar=menuBar();
    //添加菜单
    QMenu *pFile=mbar->addMenu("文件");
    //添加菜单项
    QAction *pCreate=pFile->addAction("新建");
    QAction *pOpen=pFile->addAction("打开");
    QAction *pSave=pFile->addAction("保存");
    //添加分割线
    pFile->addSeparator();
    QAction *pExit=pFile->addAction("退出");
    connect(pCreate,&QAction::triggered,[=](bool isTrigger){
        qDebug()<<"新建被按下";
        qDebug()<<isTrigger;
    });
}
 
MainWindow::~MainWindow()
{
    delete ui;
}

实现效果:

 

分割线出现的位置,取决于addSeparator()语句在代码中出现的位置。如果将它放在创建“打开”菜单项的语句后面,这条分割线就会出现在“打开”菜单项的后面。

工具栏

工具栏

工具栏其实是菜单项的快捷方式。就好像 Word 中,你可以通过菜单栏保存一个文档,也可以直接在工具栏中点击“保存”图标进行保存。

要使用菜单栏控件,需要先引入头文件。创建一个用来装载工具项的工具栏语法如下:

#include "MainWindow.h"
#include "ui_MainWindow.h"
#include <QMenuBar>
#include <QMenu>
#include <QDebug>
#include <QToolBar>
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    //菜单栏
    QMenuBar *mbar=menuBar();
    //添加菜单
    QMenu *pFile=mbar->addMenu("文件");
    //添加菜单项
    QAction *pCreate=pFile->addAction("新建");
    QAction *pOpen=pFile->addAction("打开");
    QAction *pSave=pFile->addAction("保存");
    //添加分割线
    pFile->addSeparator();
    QAction *pExit=pFile->addAction("退出");
    connect(pCreate,&QAction::triggered,[=](bool isTrigger){
        qDebug()<<"新建被按下";
        qDebug()<<isTrigger;
    });
    //工具栏:菜单栏的快捷方式
    QToolBar *mToolBar=addToolBar("tool");    //←←←←←←
}
 
MainWindow::~MainWindow()
{
    delete ui;
}

实现效果:

工具项

工具栏中的工具项是菜单栏中的部分菜单项的快捷键,所以只需要将菜单项QAction类型的指针作为参数传入工具栏QToolBar对象的addAction()中即可。实现代码如下:

#include "MainWindow.h"
#include "ui_MainWindow.h"
#include <QMenuBar>
#include <QMenu>
#include <QDebug>
#include <QToolBar>
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    //菜单栏
    QMenuBar *mbar=menuBar();
    //添加菜单
    QMenu *pFile=mbar->addMenu("文件");
    //添加菜单项
    QAction *pCreate=pFile->addAction("新建");
    QAction *pOpen=pFile->addAction("打开");
    QAction *pSave=pFile->addAction("保存");
    //添加分割线
    pFile->addSeparator();
    QAction *pExit=pFile->addAction("退出");
    connect(pCreate,&QAction::triggered,[=](bool isTrigger){
        qDebug()<<"新建被按下";
        qDebug()<<isTrigger;
    });
    //工具栏:菜单栏的快捷方式
    QToolBar *mToolBar=addToolBar("tool");
    //工具栏添加快捷键
    mToolBar->addAction(pCreate);    //←←←←←←←
}
 
MainWindow::~MainWindow()
{
    delete ui;
}

实现效果: 

可以看到,点击工具栏中的“新建”选项,和点击菜单栏中的“新建”选项效果是一样的。

如果我们希望工具栏的快捷键样式不那么单调,也可以用按钮来实现它【后续还可以用图片】。

#include "MainWindow.h"
#include "ui_MainWindow.h"
#include <QMenuBar>
#include <QMenu>
#include <QDebug>
#include <QToolBar>
#include <QPushButton>    //要使用按钮,必须引入这个头文件
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    //菜单栏
    QMenuBar *mbar=menuBar();
    //添加菜单
    QMenu *pFile=mbar->addMenu("文件");
    //添加菜单项
    QAction *pCreate=pFile->addAction("新建");
    QAction *pOpen=pFile->addAction("打开");
    QAction *pSave=pFile->addAction("保存");
    //添加分割线
    pFile->addSeparator();
    QAction *pExit=pFile->addAction("退出");
    connect(pCreate,&QAction::triggered,[=](bool isTrigger){
        qDebug()<<"新建被按下";
        qDebug()<<isTrigger;
    });
    //工具栏:菜单栏的快捷方式
    QToolBar *mToolBar=addToolBar("tool");
    //工具栏添加快捷键
    mToolBar->addAction(pCreate);
    //添加小控件
    QPushButton *b=new QPushButton(this);
    mToolBar->addWidget(b);
    b->setText("按钮实现快捷键");
}
 
MainWindow::~MainWindow()
{
    delete ui;
}

实现效果:

 

状态栏

状态栏往往出现在窗口最下面一行,比如 Word 中的状态栏,显示总页数有多少页,当前页面是第几页。

要使用状态栏,必须先引入头文件,状态栏中往往需要显示一些文字内容,因此还要引入头文件,实现状态栏的语法如下:

#include "MainWindow.h"
#include "ui_MainWindow.h"
#include <QMenuBar>
#include <QMenu>
#include <QDebug>
#include <QToolBar>
#include <QPushButton>
#include <QStatusBar>    //实现状态栏必须引入的头文件
#include <QLabel>    //实现状态栏必须引入的头文件
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    //这部分代码略过
    //状态栏
    QStatusBar *pStatusBar=statusBar();    //创建状态栏
    QLabel *pLabel=new QLabel(this);    //为标签对象指定父元素,即当前窗口
    pLabel->setText("状态栏内容");    //设置文字内容
    pStatusBar->addWidget(pLabel);    //将标签对象作为控件添加到状态栏对象中
}
 
MainWindow::~MainWindow()
{
    delete ui;
}

实现效果:

可以看到在窗口的左下角会生成一个状态栏,由于我们对状态栏对象调用了addWidget方法,并将标签对象作为参数传入,因此这个标签就被添加到状态栏中了。

P.S:addWidget()方法用于向布局中添加控件。而且是左对齐的。

我们还可以使用addWidget的另外一种简略的写法,为状态栏再添加一项内容。

//MainWindow.cpp
//说明:一个动态申请的QLabel指针作为状态栏对象的addWidget方法的参数
//在QLabel()的构造函数中可以直接指定标签内容和它的父元素
pStatusBar->addWidget(new QLabel("Content",this));

实现效果:

 

在 Word 的状态栏中,有些内容是出现在状态栏右侧的,比如“缩放比例”等,如果要使标签呈现右对齐的效果,应如何实现?

可以用addPermanentWidget方法来实现。

//MainWindow.cpp
pStatusBar->addPermanentWidget(new QLabel("Right",this));

实现效果:

 

那么问题来了,使用addPermanentWidget添加多个标签,是不是顺序也是从右往左依次添加呢?我们可以用以下代码进行实验。

//MainWindow.cpp
pStatusBar->addPermanentWidget(new QLabel("Right",this));
pStatusBar->addPermanentWidget(new QLabel("afterRight",this));     //afterRight标签在Right标签之后添加

实现效果:

结论:无论是addWidget()还是addPermanentWidget(),添加标签的顺序都是从左往右,区别在于前者是紧靠状态栏左侧,后者紧靠状态栏右侧,也就是我们常说的左对齐和右对齐。

中心窗口部件

setCentralWidget可以用来往调用它的对象中添加一个中心窗口部件。

比如,用以下代码往主窗口中添加一个标签,作为主窗口的中心窗口部件。

#include "MainWindow.h"
#include "ui_MainWindow.h"
#include <QMenuBar>
#include <QMenu>
#include <QDebug>
#include <QToolBar>
#include <QPushButton>
#include <QStatusBar>
#include <QLabel>
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    //这部分代码略过
    //中心窗口部件
    setCentralWidget(new QLabel("center"));
 
}
 
MainWindow::~MainWindow()
{
    delete ui;
}

实现效果: 

 

这样,内容为“center”的标签就作为中心窗口部件被添加到主窗口中去了,但是这么做显然意义不大,我们可以往主窗口中添加一个文本编辑部件。

要使用文本编辑部件,需要先引入头文件。实现代码如下:

#include "MainWindow.h"
#include "ui_MainWindow.h"
#include <QMenuBar>
#include <QMenu>
#include <QDebug>
#include <QToolBar>
#include <QPushButton>
#include <QStatusBar>
#include <QLabel>
#include <QTextEdit>    //实现文本编辑框必须引入的头文件
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    //这部分代码略过
    //中心窗口部件
    setCentralWidget(new QLabel("center"));
    QTextEdit *pTextEdit=new QTextEdit(this);
    setCentralWidget(pTextEdit);    //setCentralWidget是MainWindow的方法,这里省略了this
}
 
MainWindow::~MainWindow()
{
    delete ui;
}

实现效果:

P.S:通过setCentralWidget方法被添加到主窗口的中心窗口控部件默认填满整个主窗口,因此如果有多个被添加到主窗口的中心窗口控件,先添加的会被后添加的覆盖,最终只显示最后添加的中心窗口部件。

浮动窗口

浮动窗口是主窗口中可以拖动的部件。比如 Code Blocks 中的控制台窗口,一般是嵌在主窗口中,你也可以把它单独拖动出来。

要实现浮动窗口,必须先引入头文件。

主窗口调用addDockWidget()方法,这个方法有两个重载函数,按键盘的↑、↓键可以切换查看重载函数所需的参数。鼠标指向函数名,按下F1键可查看帮助文档中关于该函数的详细介绍。

这里我们选择只需要传入两个参数的重载函数,第一个参数指定浮动范围,第二个参数指定浮动窗口。

浮动范围如何指定?点击帮助文档中的Qt::DockWidgetArea,你会看到以下内容:

这是一些常数变量,可以选择的浮动方式有左浮动、右浮动、上浮动、下浮动等。

#include "MainWindow.h"
#include "ui_MainWindow.h"
#include <QMenuBar>
#include <QMenu>
#include <QDebug>
#include <QToolBar>
#include <QPushButton>
#include <QStatusBar>
#include <QLabel>
#include <QTextEdit>
#include <QDockWidget>    //使用浮动窗口必须引入的头文件
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    //这部分代码略过
    //浮动窗口
    QDockWidget *pDock=new QDockWidget(this);
    addDockWidget(Qt::LeftDockWidgetArea,pDock);    //指定浮动方式为左浮动,浮动窗口为pDock
}
 
MainWindow::~MainWindow()
{
    delete ui;
}

实现效果:

可以看到,主窗口左侧出现了一个浮动窗口,并且把中心窗口部件给挤到右边去了。随意拖动浮动窗口,还可以手动实现右浮动、上浮动和下浮动。 

注意:调用这个方法的对象是主窗口!

同样,我们也可以往浮动窗口中添加小部件,比如,往里面添加一个“浮动窗口控件”标签。

#include "MainWindow.h"
#include "ui_MainWindow.h"
#include <QMenuBar>
#include <QMenu>
#include <QDebug>
#include <QToolBar>
#include <QPushButton>
#include <QStatusBar>
#include <QLabel>
#include <QTextEdit>
#include <QDockWidget>
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    //这部分代码省略
    //浮动窗口
    QDockWidget *pDock=new QDockWidget(this);
    addDockWidget(Qt::LeftDockWidgetArea,pDock);
    //浮动窗口添加控件
    pDock->setWidget(new QLabel("浮动窗口控件"));
}
 
MainWindow::~MainWindow()
{
    delete ui;
}

实现效果:

P.S:原本我试图往浮动窗口中添加从菜单项目pCreate,执行程序后报错,报错信息为:

E:\Demo\QtDemo\BilibiliTest\05_QMainWindow\MainWindow.cpp:56: error: C2664: “void QDockWidget::setWidget(QWidget *)”: **无法将参数 1 从“QAction ”转换为“QWidget