Part 03 主窗口(Qt)
0. 本次学习Qt时主要方法:看功能效果图,看解释,分析代码,重写代码。
1. 编写学习笔记主要形式:展示程序功能,分析及总结程序设计思路,展示代码。
2. 主要参考学习资料: 《Qt学习之路》(豆子空间)。
3. 本Part内容:主窗口,了解什么是主窗口,如何为主窗口添加最基本的组成部分功能。
附:一般的主窗口组成布局
01. 展示程序功能
这个界面只能看见一个空的主窗口,不包含任何的组件。另外,能看出主窗口的标题为EmptyMainWindow.
02.从功能分析程序设计思路
对于这个空主窗口,只需要基本的一步完成,至于之前两part提到过的内容就不再累赘啦:
注:从所见到的功能开始分析需要哪些类:
第1步:知道要设计的是QMainWindow对象,需要创建继承QMainWindow的类。
注:知道哪个类后,还需要知道这个类中有哪些功能:
第2步:由于类中无其它功能,只需要将最基本的构造函数与析构函数写出即可。
注:知道需要的参数对象后,需知道包含的头文件及需用到函数个数:
第3步:要定义QApplication和QMainWindow对象,分别需要 <QApplication> 和 <QMainWindow>
第4步:由于程序功能简单,只需要一个main函数加一个类就可以完成整个程序的编写了。
03. 程序代码
// main.cpp
#include "emptymainwindow.h"
#include <QtGui/QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
EmptyMainWindow w;
w.show();
return a.exec();
}
// emptymainwindow.h
#ifndef EMPTYMAINWINDOW_H
#define EMPTYMAINWINDOW_H
#include <QtGui/QMainWindow>
class EmptyMainWindow : public QMainWindow
{
Q_OBJECT
public:
EmptyMainWindow(QWidget *parent = 0, Qt::WFlags flags = 0);
~EmptyMainWindow();
};
#endif // EMPTYMAINWINDOW_H
// emptymainwindows.cpp
#include "emptymainwindow.h"
EmptyMainWindow::EmptyMainWindow(QWidget *parent, Qt::WFlags flags)
: QMainWindow(parent, flags)
{
// Qt::WFlags 是一个设定主窗口初始状态时空白地方的模式参数
}
EmptyMainWindow::~EmptyMainWindow()
{
}
009 Program – simpleMainWindow
01. 展示程序功能
该程序只有一个简单的主窗口,主窗口上有单个选项的菜单栏,还有单个选项的工具栏。
鼠标左键点击主窗口菜单栏上的File,可以看见当鼠标移至展开菜单中的open动作时,在状态栏会出现Open a file的提示字样。同样地,当将鼠标移至工具栏上的open动作时,状态栏也出现了同样的提示。
当再在上面的基础上,点击鼠标左键,一个dialog将会被激活,显示在屏幕上。
02.从功能分析程序设计思路
这是一个附带一个显示信息对话框的简单窗口:
注:从所见到的功能开始分析需要哪些类:
第01步:知道要设计的是QMainWindow对象,需要创建继承QMainWindow的类。
第02步:在QMainWindow对象中,还能看见的是有QMenuBar、QToolBar与QStatusBar.
第03步:最后,显示给用户的是QMessageBox的界面。
第04步:状态栏,显示临时的提示信息,这个提示信息可以说是最终来源于Open这动作。
第05步:菜单栏与工具栏,提供激发Open动作的接口。
第06步:想要将这些类联接起来,只需要分别将Open动作与各个栏目连接。
注:开始分析总体结构:
第07步:QMainWindow中包含了五大类,QStatusBar, Q MenuBar, Q ToolBar, QAction, Q MessageBox.
第08步:其中,在StatusBar显示提示信息大概需要用到两个过程,
第一:建立提示信息;
第二:将提示信息关联到QAction中。
第09步:在QMenuBar与QAction关联时,需要用到一个QMainWindow提供的函数menuBar();
第10步:在QToolBar与QAction关联时,需要用到一个QMainWindow提供的addToolBar();
第11步:在建立QMessageBox时,也是经过两个过程:
第一:建立提示信息;
第二:将提示信息加入到QMessageBox对象中。
第12步:要知道,需要响应一个动作,就意味着,建立一个信号/槽 QObject::connect.
第13步:建立QAction,可以将其分解为三个过程。建快捷键,建动作相关提示语,建动作图标。
注:知道大概框架后,想想简单的主函数需要包含哪些东西:
第14步:main函数,由于没有太多的功能,在main函数中只需要惯例建QApplicaion对象。
第15步:建立自己所建立的QMainWindow继承类的对象。
第16步:将这个类的对象显示出来。
第17步:使用 return.exec();语句结束本次主函数的编写。
03. 程序代码及分析信息
// main.cpp
#include "simplemainwindow.h"
#include <QtGui/QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
simpleMainWindow w;
w.show();
return a.exec();
}
// simplemainwindow.h
#ifndef SIMPLEMAINWINDOW_H
#define SIMPLEMAINWINDOW_H
#include <QtGui/QMainWindow>
#include "ui_simplemainwindow.h"
class QAction;
class QLabel;
class simpleMainWindow : public QMainWindow
{
Q_OBJECT
public:
simpleMainWindow(QWidget *parent = 0, Qt::WFlags flags = 0);
~simpleMainWindow();
private slots:
void open();
private:
Ui::simpleMainWindowClass ui;
QAction *openAction; // 打开文件的动作指针
QLabel * msgLabel; // 用于状态栏显示信息的一个标签
};
#endif // SIMPLEMAINWINDOW_H
// simplemainwindow.cpp
#include "simplemainwindow.h"
#include <qmessagebox.h>
#include <qaction.h>
#include <qtoolbar.h>
#include <qmenu.h>
#include <qmenubar.h>
#include <qlabel.h>
simpleMainWindow::simpleMainWindow(QWidget *parent, Qt::WFlags flags)
: QMainWindow(parent, flags)
{
ui.setupUi(this);
// 一个主菜单功能的完成,可以包含三个方面,一个是菜单栏,一个是工具栏,一个是状态栏
// 完成这一个功能前提,是要创建一个动作,动作一般包括了三要素,1.本身动作名称 2. 快捷键 3. 动作图标。
// 要完成功能,然后是要将动作与相关功能函数或界面相连(使用信号/槽机制)
// 动作创建好,接下来只需要很简简地创建工具栏,菜单栏,状态栏相连即可。
// 下面开始每个功能讲解:
// QAction 有三种构造函数:
// 第一种,QAction::QAction ( QObject * parent ) 当为动作组时,该参数指向父对象
// 第二种,QAction::QAction ( const QString & text, QObject * parent ) 第一个为本动作的名称,第二个为父对象
// 第三种,QAction::QAction ( const QIcon & icon, const QString & text, QObject * parent ) 第一个为本动作图标,其它同上
openAction = new QAction(tr("&Open"), this);
// 在构造好QAction对象后,可以开始设置动作的三个基本要素:
// 第一:设定快捷键,参数的设置可参考在enum QKeySequence::StandardKey的默认参数。
openAction -> setShortcut(QKeySequence::Open);
// 第二:设置状态栏提示语句,当主菜单有状态栏时即可显示其效果
openAction -> setStatusTip(tr("Open a file."));
// 第三:设置该动作的图标,VS2010平台下,先在"Resource Files下添加.qrc(Qt Recource Collection)
// 然后在.qrc中添加相关的图标,添加后,能从对话框中看见 Resource URL,URL即为图标样式了
// 其中需要注意的是:QToolBar的图标大小默认是32*32,菜单默认是16*16。
openAction -> setIcon(QIcon(":/simpleMainWindow/Resources/Pastel_Icons_031.png"));
// 在创建好动作后,可以开始将动作与信号/槽机制与相关功能函数相连
// 关于信号,可以用 QAction::triggered()
// void QAction::triggered ( bool checked = false ) [signal]
// This signal is emitted when an action is activated by the user;
// for example, when the user clicks a menu option, toolbar button, or presses an action's shortcut key combination, or when trigger() was called.
connect(openAction, SIGNAL(triggered()), this, SLOT(open()));
// 接下来的操作是将动作加到菜单栏中,即此时需要新建菜单栏。
// 用到了父类QMainWindow中的一个函数:QMenuBar * QMainWindow::menuBar () const;
// Returns the menu bar for the main window. This function creates and returns an empty menu bar if the menu bar does not exist.
// 使用该函数时,返回的类型是QMenuBar类,然后使用下面的函数:QMenu * QMenuBar::addMenu ( const QString & title )
// Appends a new QMenu with title to the menu bar. The menu bar takes ownership of the menu. Returns the new menu.
QMenu * file = menuBar() -> addMenu(tr("&File"));
// 此时,右值是新建的菜单,然后,通过赋值号,将右值赋值至左值。
// 新建了菜单后,需要做的工作就是将已设定好的动作添加到该菜单选项中。此函数可不解释了。
file -> addAction(openAction);
// 菜单栏添加完毕后,可以考虑添加工具栏了,只是,工具栏,可以想到,它只是一个个的图标,因此,操作并没菜单栏复杂
// 可以想像,如果菜单栏有多重菜单的时候,是如何创建的,这里先不提及,所以工具栏并不需要像菜单栏那样先新建一个menu再调用menu中的类
// 工具栏,QMainWindow已经提供了一个可以直接使用的函数,addToolBar()
// void QMainWindow::addToolBar ( QToolBar * toolbar )
// This is an overloaded function. 这是一个重载函数。至于另一个函数是:
// void QMainWindow::addToolBar ( Qt::ToolBarArea area, QToolBar * 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.
QToolBar * toolBar = addToolBar(tr("&File"));
toolBar -> addAction(openAction);
// 最后是添加状态栏 QStatusBar类
// 状态栏显示的信息有三种类型:临时信息Temporary,一般信息Normal,永久信息Permanent
// Typically, a request for the status bar functionality occurs in relation to a QMainWindow object.
// QMainWindow provides a main application window, with a menu bar, tool bars, dock widgets and a status bar around a large central widget.
// The status bar can be retrieved using the QMainWindow::statusBar() function, and replaced using the QMainWindow::setStatusBar() function.
// 将默认大小设置为: sizeHint : const QSize
// This property holds the recommended size for the widget.
// If the value of this property is an invalid size, no size is recommended.
// The default implementation of sizeHint() returns an invalid size if there is no layout for this widget,
// and returns the layout's preferred size otherwise.
msgLabel = new QLabel;
msgLabel -> setMinimumSize(msgLabel -> sizeHint());
msgLabel -> setAlignment(Qt::AlignHCenter);
// QStatusBar * QMainWindow::statusBar () const
// Returns the status bar for the main window. This function creates and returns an empty status bar if the status bar does not exist.
// void QStatusBar::addWidget ( QWidget * widget, int stretch = 0 )
// Adds the given widget to this status bar, reparenting the widget if it isn't already a child of this QStatusBar object.
// The stretch parameter is used to compute a suitable size for the given widget as the status bar grows and shrinks.
// The default stretch factor is 0, i.e giving the widget a minimum of space.
// The widget is located to the far left of the first permanent widget (see addPermanentWidget()) and may be obscured by temporary messages.
statusBar() -> addWidget(msgLabel);
statusBar() -> setStyleSheet(QString("QStatusBar::item{border: 0px}")); // 让状态栏为空时,不存在分隔线
statusBar() -> setSizeGripEnabled(false); // 将右下角的大小控制点设置为允许采用的状态
}
void simpleMainWindow::open()
{
// 这里还没开始实现打开文件的操作,只是对执行open这一个Action进行模拟
// 使用QMessageBox可以建立一个带提示信息的对话框。
QMessageBox::information(NULL, tr("Open"), tr("Open a file"));
return;
}
simpleMainWindow::~simpleMainWindow()
{
}