目录
1、主窗口的概念
应用程序中的主窗口
-主窗口是与用户进行长时间交互的顶层窗口,通常是应用程序启动后显示的第一个窗口,整个程序由一个主窗口和多个对话框组成
-Qt开发平台中直接支持主窗口的概念 ,QMainWindow是Qt中主窗口的基类 ,QMainWindow继承于QWidget是一种容器类型的组件
-QMainWindow中封装了菜单栏,工具栏,状态栏等组件
2、主窗口中的菜单栏
在Qt中提供与菜单相关的类组件
-菜单栏(QMenuBar)包含多个菜单组件(QMenu),菜单是由菜单项(QAction)列表组成
-QAction被点击之后会产生一个triggered信号 ,通过信号与槽的机制能够捕捉对QAction对象的操作
在Qt主窗口中创建菜单
#include "MainWindow.h"
#include <QMenuBar>
#include <QKeySequence>
#include <QAction>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
QMenuBar* mb = menuBar(); // creates and returns an empty menu bar if the menu bar does not exist.
QMenu* menu1 = new QMenu("File(&F)", mb);
QMenu* menu2 = new QMenu("Edit(&E)", mb);
QAction* action1 = new QAction("New(&N)", menu1);
QAction* action2 = new QAction("Open(&O)...", menu1);
action1->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_N)); // 设置快捷键:QKeySequence:Qt中与快捷键相关的类 KEY:Qt中代表键值的常量
action2->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_S));
menu1->addAction(action1);
menu1->addAction(action2);
QAction* action3 = new QAction("Undo(&U)", menu1);
QAction* action4 = new QAction("Redo(&R)...", menu1);
action3->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_U));
action4->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_R));
menu2->addAction(action3);
menu2->addAction(action4);
mb->addMenu(menu1); // 菜单添加到菜单栏
mb->addMenu(menu2);
mb->setStyleSheet("background-color: rgb(255, 0, 0);");
menu1->setStyleSheet("background-color: rgb(0, 255, 0);");
}
MainWindow::~MainWindow()
{
}
3、主窗口中的工具栏
工具栏的概念和意义
-应用程序中集成各种功能实现快捷使用的一个区域,工具栏并不是应用程序中必须存在的组件
-工具栏中的元素可以是各种窗口组件 ,工具栏中的元素通常以图标按钮的方式存在
-在Qt中提供与工具栏相关的类组件
在Qt主窗口中创建工具栏
QToolBar* tb = addToolBar("Tool Bar"); // 创建工具栏
/* create action item for Tool Bar*/
QAction* action = new QAction("", tb); // 创建快捷项
/* set action property*/
action->setToolTip("Open"); // 鼠标停留于提示
action->setIcon(QIcon(":/Res/pic/open.png"));
/* add item to Tool Bar*/
tb->addAction(action); // 将快捷项添加到工具栏
QToolBar中可以加入任意的QWidget组件
#include "MainWindow.h"
#include <QToolBar>
#include <QAction>
#include <QIcon>
#include <QPushButton>
#include <QLabel>
#include <QLineEdit>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
QToolBar* tb = addToolBar("Tool Bar");
QAction* action = new QAction("", tb);
tb->setFloatable(false); // 不能悬浮
tb->setMovable(false); // 不能移动
action->setToolTip("Open");
action->setIcon(QIcon(":/res/open.png"));
tb->addAction(action);
tb->addSeparator();
QPushButton* b = new QPushButton("Button");
QLabel* l = new QLabel("Label");
QLineEdit* e = new QLineEdit();
tb->addWidget(b);
tb->addSeparator();
tb->addWidget(l);
tb->addSeparator();
tb->addWidget(e);
}
MainWindow::~MainWindow()
{
}
父子间关系
通过主窗口对象可以定位任意QAction
QAction* MainWindow::findMenuBarAction(QString text)
{
QAction* ret = NULL;
const QObjectList& list = menuBar()->children();
for(int i=0; i<list.count(); i++)
{
QMenu* menu = dynamic_cast<QMenu*>(list[i]);
if( menu != NULL )
{
QList<QAction*> actions = menu->actions();
for(int j=0; j<actions.count(); j++)
{
if( actions[j]->text().startsWith(text) )//当前的action是所指定的action,找到了,返回
{
ret = actions[j];
break;
}
}
}
}
return ret;
}
QAction* MainWindow::findToolBarAction(QString text)
{
QAction* ret = NULL;
const QObjectList& list = children(); // 包含了主窗口每一个组件
for(int i=0; i<list.count(); i++)
{
QToolBar* toolBar = dynamic_cast<QToolBar*>(list[i]); //只有一个工具栏组件可以转换成功,其它失败返回NULL
if( toolBar != NULL )//找到了工具栏
{
QList<QAction*> actions = toolBar->actions(); // 实际上面的所有转换步骤可以只用一步:QList<QAction*> actions = toolBar()->actions();
for(int j=0; j<actions.count(); j++)
{
if( actions[j]->toolTip().startsWith(text) )
{
ret = actions[j];
break;
}
}
}
}
return ret;
}
4、主窗口中的状态栏
状态栏的概念和意义
-状态栏是应用程序中输出简要信息的区域,状态栏一般位于主窗口的最底部
-状态栏中的消息类型 :实时消息,如:当前程序状态 ;永久消息,如:程序版本号,机构名称 ;进度消息,如:进度条提示,百分比提示
-在Qt中提供与状态栏相关的类组件
Qt状态栏的设计原则
-左边的区域用于输出实时消息,右边的区域用于设置永久消息
-addWidget()在状态栏左半部分添加组件 ,addPermanentWidget()在状态栏右半部份添加组件
下面演示如何实时计算鼠标的位置
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QPlainTextEdit>
#include <QLabel>
class MainWindow : public QMainWindow
{
Q_OBJECT
QPlainTextEdit m_edit;
QLabel m_lable;
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
protected slots:
void onCursorPositionChanged(); // QPlainTextEdit能够触发与编辑操作相关的信号 ,可以映射信号到自定义槽函数(具体自行查阅帮助文档)
};
#endif // MAINWINDOW_H
#include "MainWindow.h"
#include <QPushButton>
#include <QLabel>
#include <QLineEdit>
#include <QStatusBar>
#include <QDebug>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
this->setCentralWidget(&m_edit);
QStatusBar* sb = statusBar();
QLabel* l = new QLabel("Label");
QLineEdit* e = new QLineEdit();
QPushButton* b = new QPushButton("Button");
sb->setStyleSheet("background-color: rgb(0, 255, 0);");
l->setStyleSheet("background-color: rgb(38, 70, 255);");
m_lable.setStyleSheet("background-color: rgb(255, 0, 0);");
m_lable.setFixedWidth(140);
e->setStyleSheet("background-color: rgb(255, 70, 255);");
b->setStyleSheet("background-color: rgb(38, 255, 255);");
sb->addPermanentWidget(l);
sb->addPermanentWidget(e);
sb->addPermanentWidget(b);
sb->addWidget(&m_lable);
connect(&m_edit, SIGNAL(cursorPositionChanged()), this, SLOT(onCursorPositionChanged())); //This signal is emitted whenever the position of the cursor changed.
onCursorPositionChanged();
}
void MainWindow::onCursorPositionChanged()//检测光标位置的变化
{
int pos = m_edit.textCursor().position(); // 当前光标的字符位置
qDebug() << pos << endl;
QString text = m_edit.toPlainText();
int col = 0;
int ln = 0;
int flag = -1;
for(int i=0; i<pos; i++)
{
if( text[i] == '\n' )
{
ln++;
flag = i; // 记录当前位置
}
} // 成功得到行数
flag++; // 最后一个换行符后一个位置
col = pos - flag;
m_lable.setText("Ln: " + QString::number(ln + 1) + " Col: " + QString::number(col + 1));
}
MainWindow::~MainWindow()
{
}
5、主窗口中的停靠组件(QDockWidget)
QDockWidget
MainWindow::MainWindow(QWidget *parent): QMainWindow(parent), ui(new Ui::MainWindow)
{
ui->setupUi(this);
// 1. 新建一个要插入停靠窗体的控件,常用的有QListWidget和QTextEdit。
QTextEdit* te = new QTextEdit(this);
te->setText("Main Window");
te->setAlignment(Qt::AlignCenter);
setCentralWidget(te); // 设置为中央窗口
// 2. 创建一个停靠窗口
QDockWidget* dock = new QDockWidget("DockWindow1", this);
// 设置特征:可移动,可关闭,可浮动
dock->setFeatures(QDockWidget::DockWidgetMovable | QDockWidget::DockWidgetClosable | QDockWidget::DockWidgetFloatable);
// 设置停靠区域:可在主窗口左右侧
dock->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
// 3. 为停靠窗口添加组件
QTextEdit* te1 = new QTextEdit();
te1->setText("Hello");
dock->setWidget(te1);
// 4. 为主窗口添加停靠窗口,在右边
addDockWidget(Qt::RightDockWidgetArea, dock);
}
6、Qt 中的文本编辑组件
Qt中支待3种常用的文本编辑组件
-QLineEdit:单行文本编辑组件
-QTextEdit:多行富文本编辑组件
-QPlainTextEdit:多行普通文本编辑组件
Qt中常用文本编辑组件的内置功能
1、右键弹出式菜单
2、快捷键功能 , 复制,粘贴,剪切,等
文本编辑组件的对比试验
MainWindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QtGui/QMainWindow>
#include <QLineEdit>
#include <QPlainTextEdit>
#include <QTextEdit>
class MainWindow : public QMainWindow
{
Q_OBJECT
QLineEdit lineEdit;
QPlainTextEdit plainEdit;
QTextEdit textEdit;
public:
MainWindow(QWidget *parent = 0);
~MainWindow();
};
#endif // MAINWINDOW_H
MainWindow.cpp
#include "MainWindow.h"
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent),
lineEdit(this), plainEdit(this), textEdit(this)
{
resize(600, 420);
lineEdit.move(20, 20);
lineEdit.resize(560, 100);
lineEdit.insert("QLineEdit");
lineEdit.insert("\n");
lineEdit.insert("<img src=\"C:\\Users\\wss\\Desktop\\a.jpg\" />");
plainEdit.move(20, 130);
plainEdit.resize(560, 130);
plainEdit.insertPlainText("QPlainTextEdit");
plainEdit.insertPlainText("\n");
plainEdit.insertPlainText("<img src=\"C:\\Users\\wss\\Desktop\\a.jpg\" />");
textEdit.move(20, 270);
textEdit.resize(560, 130);
textEdit.insertPlainText("QTextEdit");
textEdit.insertPlainText("\n");
textEdit.insertHtml("<img src=\"C:\\Users\\wss\\Desktop\\a.jpg\" />");
}
MainWindow::~MainWindow()
{
}
QPlainTextEdit内部的文档结构
- QPlainTextEdit通过QTextDocument对象存储文本数据,QTextCursor负责光标的行为 ,QPlainTextEdit本身只负责界面形态的显示
- QTextDocument是表示文本以及文本属性的数据类
◆ 设置文本的属性:排版,字体,标题,等
◆ 获取文本参数:行数,文本宽度,文本信息,等
◆ 实现标准操作:撒销,重做,查找,打印,等
- QTextCursor 提供大量接口访问和修改QTextDocuments
- QPlainTextEdit提供了丰富的交互功能接口
◆ 复制(Copy) ,粘贴(Paste), 剪切(Cut), 撒销(Undo) , 重做(Redo), 删除(Delete)
7、NotePad分析
增量模型适合于文本编辑器的开发 :需求相对固定 ,功能之间的耦合性弱
界面开发
文件操作逻辑(功能交互)
Qt程序中的配置文件
应用程序在运行后都有一个初始化的状态 ,一般而言: 程序的初始状态是最近一次运行退出前的状态
-程序退出前保存状态参数到文件(数据库)
◆ 文本文件格式(XML, Json, 等)
◆ 轻量级数据库(Access, SQLite, 等)
◆ 私有二进制文件格式
-程序再次启动时读出状态参数并恢复
QT中配置文件类的设计与实现
-通过二进制数据流将状态参数直接存储于文件中
-优势:参数的存储和读取简单高效,易于编码实现最终文件为二进制格式,不易被恶意修改
主窗口的状态参数 :应用程序必须保存和恢复主窗口的状态参数 (位 置 ,大小),应用程序收到关闭事件时进行状态参数的保存
实现界面+完善的功能
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets printsupport
TARGET = NotePad
TEMPLATE = app
SOURCES += main.cpp\
MainWindowSlots.cpp \
MainWindowUI.cpp \
FindDialog.cpp \
ReplaceDialog.cpp \
AboutDialog.cpp \
AppConfig.cpp
HEADERS += MainWindow.h \
FindDialog.h \
ReplaceDialog.h \
AboutDialog.h \
AppConfig.h
RESOURCES += \
Res.qrc
待增加的功能:富文本与多文档的支持,编码转化 ...