一、QMainWindow
QMenuBar:菜单栏
QMenu: 菜单
QAction: 动作
QToolBar: 工具栏
QStatusBar: 状态栏
//cpp文件(本程序只需要写cpp文件即可)
//1.创建新项目 选择MainWindow
#include "mainwindow.h"
#include <QMenuBar> //菜单栏
#include <QMenu> //菜单
#include <QAction> //菜单项
#include <QToolBar> //工具栏
#include <QDockWidget> //浮动窗口
#include <QStatusBar> //状态栏
#include <QTextEdit> //文本编辑
#include <QLabel> //标签
#include <QProgressBar> //进度条
#include <QFileDialog> //打开文件对话框
#include <QMessageBox> //消息提示框
#include <QFontDialog> //字体大小种类设置框
#include <QColorDialog> //字体颜色设置框
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
setWindowTitle("主窗口");
setWindowIcon(QIcon(":/mw_images/title.png"));
setFixedSize(1000, 800);
//2.唯一菜单栏(无图的是菜单,有图的是工具栏)
QMenuBar *menubar = this->menuBar();
//3.增加菜单到菜单栏中
QMenu *fileMenu = menubar->addMenu("文件");
QMenu *editMenu = menubar->addMenu("编辑");
QMenu *setMenu = menubar->addMenu("设置");
//4.addaction给每个菜单增加两个菜单项,并QAction *接收,后续connect拉姆达表达式绑定操作
//addSeparator 视觉隔断
QAction *actOpen = fileMenu->addAction(QIcon(":/mw_images/open.png"), "打开文件");
fileMenu->addSeparator();
QAction *actClose = fileMenu->addAction(QIcon(":/mw_images/close.png"), "关闭文件");
QAction *actCopy = editMenu->addAction(QIcon(":/mw_images/copy.png"), "拷贝");
editMenu->addSeparator();
QAction *actPaste = editMenu->addAction(QIcon(":/mw_images/paste.png"), "粘贴");
QAction *actFont = setMenu->addAction(QIcon(":/mw_images/font.png"), "设置字体");
setMenu->addSeparator();
QAction *actColor = setMenu->addAction(QIcon(":/mw_images/color.png"), "设置颜色");
//5.添加多个工具栏(右键可以查看工具栏名字和浮动窗口,并可设置是否可见)
QToolBar *fileTool = this->addToolBar("打开和关闭文件");
QToolBar *editTool = addToolBar("拷贝和粘贴");
QToolBar *setTool = addToolBar("字体和颜色");
//6.给每个工具栏增加工具项(来自菜单的菜单项)
fileTool->addAction(actOpen);
fileTool->addSeparator();
fileTool->addAction(actClose);
fileTool->setAllowedAreas(Qt::TopToolBarArea | Qt::BottomToolBarArea);//设置上下停靠
fileTool->setMovable(true);//设置可拖动
fileTool->setFloatable(false);//设置不可浮动(不管拖到哪里,都会回到原位)
editTool->addAction(actCopy);
editTool->addSeparator();
editTool->addAction(actPaste);//默认可拖动可浮动
setTool->addAction(actFont);
setTool->addSeparator();
setTool->addAction(actColor);
//7.设置唯一中央部件(文本编辑器)
QTextEdit *te = new QTextEdit(this);
setCentralWidget(te); //(this->setcentralwidget(te))
//8.设置多个浮动窗口(没详细讲干什么用的)(右键可选择是否可见 可选择脱离主窗口)
QDockWidget *dw1 = new QDockWidget("浮动窗口", this);
QDockWidget *dw2 = new QDockWidget("浮动窗口2", this);
//9.设置浮动窗口可停靠的区域,以及默认停靠区域
dw1->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);
this->addDockWidget(Qt::LeftDockWidgetArea, dw1);
dw2->setAllowedAreas(Qt::TopDockWidgetArea | Qt::BottomDockWidgetArea | Qt::RightDockWidgetArea);
this->addDockWidget(Qt::RightDockWidgetArea, dw2);
//10.设置唯一状态栏(主窗口下方的状态栏,添加一个label,一个progress进度条)
QLabel *lb = new QLabel(this);
lb->setText("没有文件被打开");
QProgressBar *prgBar = new QProgressBar(this);//进度条
prgBar->setValue(0);
QStatusBar *staBar = this->statusBar();
staBar->addWidget(lb);
staBar->addWidget(prgBar);
//11.connect QAction *项(菜单项、工具项)和拉姆达表达式
//11.1打开文件(QFileDialog::getOpenFileName())
connect(actOpen, &QAction::triggered, [=](){
QString fileName = QFileDialog::getOpenFileName(this, "打开文本文件", ".", "文本文件 (*.h *.cpp *.txt)"); //打开文件的弹出框
if (fileName.isEmpty())
{
QMessageBox::information(this, "文件选择错误", "没有文件被选中");
return;
} //选择文件为空的消息提示框
te->setText(fileName);//中央部件(文本编辑器)内容更新
lb->setText(fileName + "被打开");//状态栏更新
prgBar->setValue(55);//设置进度条为55
});
//11.2关闭文件(清除文本编辑器的内容,更新状态栏)
connect(actClose, &QAction::triggered, [=](){
te->clear();
lb->setText("没有文件被打开");
prgBar->setValue(0);
});
//11.3 拷贝、粘贴内容
connect(actCopy, &QAction::triggered, te, &QTextEdit::copy);
connect(actPaste, &QAction::triggered, te, &QTextEdit::paste);
// connect(actCopy, &QAction::triggered, [=](){
// te->copy();
// });
// connect(actPaste, &QAction::triggered, [=](){
// te->paste();
// });
//11.4 设置字体大小和种类(打开字体选择框 缺点是只能全部设置为相同字体)
connect(actFont, &QAction::triggered, [=](){
bool isOk;
QFont font = QFontDialog::getFont(&isOk);
if (isOk) //字体选择框的OK 表示确认
{
te->setFont(font);
}
});
//11.5 设置字体颜色
connect(actColor, &QAction::triggered, [=](){
QColor color = QColorDialog::getColor();
te->setTextColor(color);
});
}
效果展示
二、事件
两种虚函数:事件处理的统一入口bool event(QEvent *event) 特定事件处理入口
bool event(QEvent *event); //事件处理的统一的入口
void mousePressEvent(QMouseEvent *e); --- 鼠标按下事件 //特定事件处理器
widget.h:
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QEvent> //事件
#include <QMouseEvent> //鼠标事件(左右点击、双击、滚动、移动...)
#include <QWheelEvent> //滚轮滚动事件
#include <QKeyEvent> //键盘事件
#include <QTimerEvent> //定时器事件
#include <QPaintEvent> //绘图事件(窗口大小改变 内容改变)
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = 0);
~Widget();
//事件的总入口 //重写事件处理器
bool event(QEvent *event);
//鼠标相关的特定事件 //重写特定的事件处理器
void mousePressEvent(QMouseEvent *event); //鼠标点击按下事件
void mouseReleaseEvent(QMouseEvent *event); //鼠标释放的事件
void mouseMoveEvent(QMouseEvent *event); //鼠标移动的事件
void mouseDoubleClickEvent(QMouseEvent *event); //鼠标双击的事件
void wheelEvent(QWheelEvent *event); //滚轮的事件
//键盘相关的特定事件
void keyPressEvent(QKeyEvent *event);
void keyReleaseEvent(QKeyEvent *event);
//定时器事件
void timerEvent(QTimerEvent *event);
//绘图事件
void paintEvent(QPaintEvent *event);
};
#endif // WIDGET_H
widget.cpp:
#include "widget.h"
#include <QDebug>
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
startTimer(3000);//QWidget类自带定时器
}
Widget::~Widget()
{
}
//重写事件函数的定义
//1.事件总入口
bool Widget::event(QEvent *event)
{
//举例在总入口处理几个事件
if (event->type() == QEvent::MouseButtonPress)
{
qDebug() << "event(鼠标点击事件)";
//return false;
}
else if (event->type() == QEvent::KeyPress)
{
qDebug() << "event(键盘按下事件)";
}
else if (event->type() == QEvent::Timer)
{
qDebug() << "event(定时器超时事件)";
}
//为了不影响原有的行为,需要调用基类的event()函数
return QWidget::event(event); //写了这个才能执行特殊事件处理,表示该怎么处理怎么处理
}
//2.特定的事件处理器
//2.1鼠标相关的特定事件
void Widget::mousePressEvent(QMouseEvent *event) //鼠标点击按下事件
{
qDebug() << "mousePressEvent()";
qDebug() << event->pos(); //表示在窗口中的位置
// qDebug() << event->x();
// qDebug() << event->y();
// qDebug() << event->globalPos(); //表示在电脑屏幕中的位置
// qDebug() << event->globalX();
// qDebug() << event->globalY();
if (event->button() == Qt::LeftButton) //event的button事件 Qt的leftbutton事件
{
qDebug() << "左键";
}
else if (event->button() == Qt::RightButton)
{
qDebug() << "右键";
}
else if (event->button() == Qt::MiddleButton)
{
qDebug() << "中键";
}
}
//2.2鼠标释放和鼠标移动
void Widget::mouseReleaseEvent(QMouseEvent *event) //鼠标释放的事件
{
qDebug() << "mouseReleaseEvent()";
qDebug() << event->pos();
}
void Widget::mouseMoveEvent(QMouseEvent *event) //鼠标移动的事件
{
qDebug() << "mouseMoveEvent()";
qDebug() << event->pos();
}
//2.3鼠标双击
void Widget::mouseDoubleClickEvent(QMouseEvent *event)//鼠标双击的事件
{
qDebug() << "mouseDoubleClickEvent()";
qDebug() << event->pos();
if (event->button() == Qt::LeftButton)
{
qDebug() << "左键双击";
}
else if (event->button() == Qt::RightButton)
{
qDebug() << "右键双击";
}
else if (event->button() == Qt::MiddleButton)
{
qDebug() << "中键双击";
}
}
//2.4滚轮
void Widget::wheelEvent(QWheelEvent *event) //滚轮的事件
{
qDebug() << "wheelEvent()";
qDebug() << event->pos();
qDebug() << event->delta();
}
//2.5键盘
void Widget::keyPressEvent(QKeyEvent *event)
{
qDebug() << "keyPressEvent";
qDebug() << (char)event->key();
}
void Widget::keyReleaseEvent(QKeyEvent *event)
{
qDebug() << "keyReleaseEvent";
qDebug() << (char)event->key();
}
//2.6 定时器
void Widget::timerEvent(QTimerEvent *event)
{
qDebug() << "timerEvent";
}
//2.7 绘图
void Widget::paintEvent(QPaintEvent *event)
{
static int i = 0;
qDebug() << "paintEvent" << i++;
}
效果展示
三、事件过滤器
1) 安装事件过滤器
le->installEventFilter(this); //从QObject继承出来的对象,可以注册一个事件过滤器,所有的事件先交给事件过滤器处理
2) 重写事件过滤器
bool eventFilter(QObject *watched, QEvent *event);
/*
参数:
watched: 对象
event: 事件
返回值:
true: 事件已处理
false: 事件未处理
*/
widget.h:
public里多加一个bool eventFilter(QObject *watched, QEvent *event);
widget.cpp:
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
setWindowTitle("事件过滤器");
//1.使用事件过滤器的第一步:给le_input安装事件过滤器,凡是到达te_input的事件,都先委托给主窗口先去处理
//te_input是委托方;主窗口是被委托方
ui->te_input->installEventFilter(this);
//2.事件过滤器使用的第二步,重新被委托方的事件过滤器
//true 表示对该事件的处理完毕,false 表示对该事件处理没有完
bool Widget::eventFilter(QObject *watched, QEvent *event)
{
if (event->type() == QEvent::KeyPress) //event->type()判断事件类型是否为键盘
{
QKeyEvent *tmp = static_cast<QKeyEvent*>(event); //强转(大转小),方便后续判断
if (tmp->key() <= Qt::Key_9 && tmp->key() >= Qt::Key_0)
{
QString s1 = ui->te_output_1->toPlainText();
s1 += QString(tmp->key()); //QString的+=使用
ui->te_output_1->setText(s1); //ui指针别忘了加
//return true; //是否return表示是否不把字符打印在过滤前文本
}
else if (tmp->key() <= Qt::Key_Z && tmp->key() >= Qt::Key_A)
{
QString s1 = ui->te_output_2->toPlainText();
s1 += QString(tmp->key());
ui->te_output_2->setText(s1);
return true;
}
else if (tmp->key() == Qt::Key_Tab)
{
ui->te_output_1->clear();
return true;
}
else if (tmp->key() == Qt::Key_Shift)
{
ui->te_output_2->clear();
return true;
}
}
//对于不感兴趣的事件,继续调用基类的事件过滤器,维持原有的行为
QWidget::eventFilter(watched, event);
}