Qt基础知识及代码
2023-12-21 07:08:12
文章目录
文件介绍快捷键
// 宏,允许类中使用信号和槽机制
Q_OBJECT
快捷键
// 运行
Ctrl + r
// 编译
Ctrl + b
// 查找
Ctrl + f
// 整行移动
Ctrl + Shift + ↑ 或 ↓
// 帮助文档
F1
// 自动对齐
Ctrl + r
// 同名之间的.h文件和.cpp文件之间切换
F4
设置窗口属性
-
修改窗口的标题
-
this->setWindowTitle("MyProject");
-
-
设置窗口的大小,设置完成可以拉伸
-
this->resize(600, 400);
-
-
设置固定大小,设置完成不可拉伸
-
this->setFixedSize(600, 400);
-
控件
创建按钮
包含头文件
#include <QPushButton>
调用类的构造函数创建按钮
QPushButton* a = new QPushButton();
显示按钮
// 另外开一个窗口显示按钮
a->show();
// 设置按钮的父对象为窗口,这样按钮就在窗口上显示
a->setParent(this);
设置按钮的属性
// 设置按钮的内容
a->setText("按钮");
// 设置按钮的位置
a->move(100, 100);
// 设置按钮的大小
a->setFixedSize(20, 10);
对象树
- 当创建的对象在堆区时候,如果指定的父亲是
QObject
派生下来的类或者QObject
子类派生下来的类,可以不用管理释放的操作,将对象会放入到对象树中。 - 一定程度上简化了内存回收机制
坐标系
- 左上角为 (0, 0)
- x以右为正方向
- y以下为正方向
信号和槽
-
连接团数:connect
-
参数
- 参数1 信号的发送者
- 参数2 发送的信号(函数的地址)
- 参数3 信号的接受者
- 参数4处理的槽经数(函数的地址)。
-
松散耦合
-
实现 点击按钮 关闭窗口的案例
-
connect(a, &QPushButton::clicked, this, &Widget::close);
-
自定义的信号和槽
-
自定义信号
- 写到
signals
下 - 返回
void
- 需要声明,不需要实现
- 可以有参数,可以重载
- 写到
-
自定义槽函数
- 返回
void
- 需要声明,也需要实现
- 可以有参数,可以重载
- 写到
public slot
下或者public
或者全局函数
- 返回
-
触发自定义的信号
emit
自定义信号
-
案例-下课后,老师触发饿了信号,学生响应信号,请客吃饭
-
创建
Teacher
类 和Student
类// teacher.h文件 #ifndef TEACHER_H #define TEACHER_H #include <QObject> class Teacher : public QObject { Q_OBJECT public: explicit Teacher(QObject *parent = nullptr); signals: void hungry(); void hungry(QString foodName); }; #endif // TEACHER_H // teacher.cpp文件 #include "teacher.h" Teacher::Teacher(QObject *parent) : QObject{parent} {} // student.h文件 #ifndef STUDENT_H #define STUDENT_H #include <QObject> class Student : public QObject { Q_OBJECT public: explicit Student(QObject *parent = nullptr); void treat(); void treat(QString foodName); signals: }; #endif // STUDENT_H // student.cpp文件 #include "student.h" #include <QDebug> Student::Student(QObject *parent) : QObject{parent} {} void Student::treat() { qDebug() << "请老师吃饭"; } void Student::treat(QString foodName) { qDebug() << "请老师吃饭,老师要吃:" << foodName.toUtf8().data(); } // widget.h文件 #ifndef WIDGET_H #define WIDGET_H #include <QWidget> #include "teacher.h" #include "student.h" class Widget : public QWidget { Q_OBJECT public: Widget(QWidget *parent = nullptr); ~Widget(); private: Teacher *tt; Student *st; void classIsOver(); }; #endif // WIDGET_H // widget.cpp文件 #include "widget.h" #include <QPushButton> Widget::Widget(QWidget *parent) : QWidget(parent) { // 创建一个老师对象 this->tt = new Teacher(this); // 创建一个学生对象 this->st = new Student(this); // 老师饿了, 学生请客的连接 void(Teacher:: *teacherSignal)(QString) = &Teacher::hungry; void(Student:: *studentSolt)(QString) = &Student::treat; connect(tt, teacherSignal, st, studentSolt); // 调用下课的函数 // classIsOver(); // 点击一个 下课按钮,再触发下课 QPushButton* a = new QPushButton("下课", this); this->setFixedSize(600, 400); a->move(100, 100); // 点击按钮 触发下课 // connect(a, &QPushButton::clicked, this, &Widget::classIsOver); // 无参信号和槽连接 void(Teacher:: *teacherSignal2)(void) = &Teacher::hungry; void(Student:: *studentSolt2)(void) = &Student::treat; connect(tt, teacherSignal2, st, studentSolt2); // 信号连接信号 connect(a, &QPushButton::clicked, tt, teacherSignal2); // 断开信号 disconnect(tt, teacherSignal2, st, studentSolt2); } Widget::~Widget() {} void Widget::classIsOver() { // 下课函数,调用后触发老师饿了的信号 emit tt->hungry("宫保鸡丁"); // 触发hungry()信号 } //Qt4版本以前的信号和槽连接方式 //利用Qt4信号槽连接无参版本 //Qt4版本底层SIGNAL(hungry()) connect(tt, SIGNAL(hungry()), st, SLOT(treat())); //Qt4版本优点:参数直观,缺点:类型不做检测 //Qt5以上支持Qt4的版本写法,反之不支持 int ret = []()->int{return 1000;}(); qDebug() << ret; QPushButton *btn = new QPushButton("btn2", this); btn->move(100, 0); connect(btn, &QPushButton::clicked, this, [=](){ this->close(); emit tt->hungry("宫保鸡丁"); });
-
当自定义信号和槽发生重载的解决
重载自定义信号和槽的代码如上
- 需要利用函数指针 明确指向 函数的地址
void(Teacher *tSingal) (Qstring)=&Teacher::hungry
QString
转成char*
.ToUtf8()
转为QByteArray
.Data()
转为Char*
- 信号可以连接信号
- 断开信号
disconnect
拓展
- 信号是可以连接信号
- 一个信号 可以连接 多个槽函数
- 多个信号 可以连接 同一个槽函数
- 信号和槽函数的参数 必须类型一一对应
- 信号和槽的参数个数 是不是要一致?信号的参数个数 可以多余槽函数的参数个数
Lambda表达式11.10
[]
标识符名函数=
值传递&
引用传递
()
参数{}
实现体mutable
修饰 值传递变量,可以修改拷贝出的数据,改变不了本体。- 返回值
int ret = []()->int{return 1000;}();
QMainWindow
- 菜单栏最多有一个
QMenuBar *bar=MenuBar();
setMenuBar(bar);
QMenu *fileMenu = bar->addMenu(文件")
创建菜单QAction *newAction = fileMenu->addAction(“新建");
创建菜单项- 添加分割线
fileMenu->addSeparator);
- 工具栏 可以有多个
QToolBar *toolbar = newQToolBar(this)
aadToolBar(默认停靠区域,toolbar);
Qt:LefToolBarArea
- 设置 后期停靠区域,设置浮动,设置移动
- 添加菜单项 或者添加 小控件
- 状态栏 最多一个
QStatusBar *stBar=statusBar();
- 设置到窗口中
setStatusBar(stBar);
stBar->addwidget(label);
放左侧信息stBar->addPermanentWidket(label2);
放右侧信息
- 铆接部件 (浮动窗口) 可以多个
QDockWidget
addDockWidget
默认停靠区域,浮动窗口指针- 设置后期停靠区域
- 设置核心部件 只能一个
setCentralWidget(edit);
// 在mainwindow.cpp
#include "mainwindow.h"
#include <QMenuBar>
#include <QMenu>
#include <QToolBar>
#include <QPushButton>
#include <QStatusBar>
#include <QLabel>
#include <QDockWidget>
#include <QTextEdit>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
// 重置窗口大小
this->resize(600, 400);
// 菜单栏 只能最多有一个
// 菜单蓝创建
QMenuBar *bar = this->menuBar();
// 将菜单栏放入到窗口中
this->setMenuBar(bar);
// 创建菜单
QMenu *fileMenu = bar->addMenu("文件");
QMenu *editMenu = bar->addMenu("编辑");
// 创建菜单项
QAction *newAction = fileMenu->addAction("新建");
// 添加分割线
fileMenu->addSeparator();
QAction *openAction = fileMenu->addAction("打开");
// 工具栏 可以有多个
QToolBar *toolBar = new QToolBar(this);
this->addToolBar(Qt::LeftToolBarArea, toolBar);
// 后期设置 只允许 左右停靠
toolBar->setAllowedAreas(Qt::LeftToolBarArea | Qt::RightToolBarArea);
// 设置浮动
toolBar->setFloatable(false);
// 设置移动 (总开关)
toolBar->setMovable(false);
// 工具栏中可以设置内容
toolBar->addAction(newAction);
// 添加分割线
toolBar->addSeparator();
toolBar->addAction(openAction);
// 工具栏中添加控件
QPushButton *btn = new QPushButton("aa", this);
toolBar->addWidget(btn);
// 状态栏 最多有一个 (函数)
QStatusBar *stBar = statusBar();
// 设置到窗口中
this->setStatusBar(stBar);
// 放标签控件到状态栏上
QLabel *label = new QLabel("提示信息", this);
stBar->addWidget(label);
QLabel *label2 = new QLabel("右侧提示信息", this);
stBar->addPermanentWidget(label2);
// 铆接部件 (浮动窗口) 可以有多个
QDockWidget *dockWidget = new QDockWidget("浮动", this);
addDockWidget(Qt::TopDockWidgetArea, dockWidget);
// 设置后期停靠区域,只允许上下
dockWidget->setAllowedAreas(Qt::TopDockWidgetArea | Qt::BottomDockWidgetArea);
// 设置中心部件 只能一下
QTextEdit *edit = new QTextEdit(this);
this->setCentralWidget(edit);
}
MainWindow::~MainWindow() {}
资源文件
- 将图片文件 拷贝到项目位置下
- 右键项目 -> 添加新文件 ->
Qt->Qtrecourse File
-> 给资源文件起名 res
生成res.qrc
open in editor
编辑资源- 添加前缀 添加文件
- 使用
": + 前缀名 + 文件名"
ui->actionnew->setIcon(QIcon(":/icon/8666681_edit_icon.png"));
对话框
分类
- 模态对话框 不可以对其他窗口进行操作阻塞
QDialogdlg(this);
dlg.exec();
- 非模态对话框 可以对其他窗口进行操作
- 防止一闪而过 创建到堆区
QDialog *dlg2 = new QDialog(this);
dlg2->show();
dlg2->setAttribute(Qt::WA_DeleteOnClose);
//55号属性
标准对话框-消息对话框
QMessageBox
静态成员函数创建对话框- 错误、信息、提问、警告
- 参数1 父亲 参数2 标题 参数3 显示内容 参数4 按键类型 参数5 默认关联回车按键
- 返回值 也是
StandardButton
类型,利用返回值判断用户的输入
其他标准对话框
- 颜色对话框
QColorDialog::getColor
- 文件对话框
QFileDialog::BetOpenFileName
(父亲,标题,默认路径,过滤文件) - 字体对话框
QFontDialog::getFont
// 在mainwindows.cpp文件中
#include "mainwindow.h"
#include "./ui_mainwindow.h"
#include <QAction>
#include <QDialog>
#include <QDebug>
#include <QMessageBox>
#include <QColorDialog>
#include <QString>
#include <QFileDialog>
#include <QFontDialog>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
// 点击新建按钮 弹出一个对话框
connect(ui->actionNew, &QAction::triggered, this, [=](){
// QDialog dlg(this);
// dlg.resize(200, 100);
// dlg.exec(); // 阻塞状态
// qDebug() << "模态对话框弹出来";
// QDialog *dlg2 = new QDialog(this);
// dlg2->resize(200, 100);
// dlg2->show();
// dlg2->setAttribute(Qt::WA_DeleteOnClose); // 55号 属性
// qDebug() << "非模态对话框弹出来";
// 消息对话框
// 错误对话框 (静态成员函数 通过类名调用)
// QMessageBox::critical(this, "critical", "错误");
// 信息对话框
// QMessageBox::information(this, "info", "信息");
// 提问对话框
// 参数1 父亲 参数2 标题 参数3 提示内容 参数4 按键类型 参数5 默认关联回车按键
// if (QMessageBox::Save == QMessageBox::question(this, "ques", "提问", QMessageBox::Save | QMessageBox::Cancel, QMessageBox::Cancel))
// {
// qDebug() << "保存";
// }else {
// qDebug() << "取消";
// }
// 警告对话框
// QMessageBox::warning(this, "warning", "警告");
// 其他对话框
// 颜色对话框
//QColor color = QColorDialog::getColor(QColor(255, 0, 0));
//qDebug() << "r = " << color.red() << "g = " << color.green() << "b = " << color.blue();
// 文件对话框 参数1 父亲 参数2 标题 参数3 默认打开路径 参数4 过滤文件格式
// 返回值是 选取的路径
//QString str = QFileDialog::getOpenFileName(this, "打开文件", "C:\\Users\\admin\\Desktop", "(*.txt");
//qDebug() << str;
// 字体对话框
bool flag;
QFont font = QFontDialog::getFont(&flag, QFont("华文彩云", 36));
qDebug() << "字体: " << font.family().toUtf8().data() << "字号" << font.pointSize() << "是否加粗" << font.italic();
});
}
MainWindow::~MainWindow()
{
delete ui;
}
界面布局
- 实现登陆窗口
- 利用布局方式给窗口进行美化
- 选取
widget
进行布局,水平布局、垂直布局、栅格布局 - 给用户名、密码、登陆、退出按钮进行布局
- 默认窗口和控件之间有 6 间隙,可以调整
layoutLeftMargin
- 利用弹簧进行布局
控件
按钮组
QPushButton
常用按钮QToolButton
工具按钮 用于显示图片,如图想显示文字,修改风格:toolButtonStyle
,凸起风格autoRaise
radioButton
单选按钮,设置默认ui->rBtnMan->setChecked(true)
checkbox
多选按钮,监听状态,2选中 1半选 0未选中
// 设置单选按钮 男默认选中
ui->radioButton->setChecked(true);
// 选中女后 打印信息
connect(ui->radioButton, &QRadioButton::clicked, this, [=]() {
qDebug() << "选中了女";
});
// 多选按钮 2是选中 0是未选择中 1是半选
connect(ui->checkBox, &QCheckBox::stateChanged, [=](int state){
qDebug() << state;
});
QListWidget列表容器
QListWidgetitem *item
一行内容ui->listWidget->addltem(item)
- 设置居中方式
item->setTextAlignment(Qt:AlignHCenter);
- 可以利用
addItems
一次性添加整个诗内容
// // 利用listWidget 写诗
// QListWidgetItem *item = new QListWidgetItem("锄禾日当午");
// // 将一行诗放入到listWidget控件中
// ui->listWidget->addItem(item);
// item->setTextAlignment(Qt::AlignHCenter);
//QStringList QList<QString>
QStringList list;
list << "aaa" << "aaaaaaa" << "aaaaaaaaaa" << "aaaaaaaaaa";
ui->listWidget->addItems(list);
QTreeWidget树控件
- 设置头
ui->treeWidget->setHeaderlabels(QstringList() << "英雄" << "英雄介绍" )
- 创建根节点
QTreeWidgetitem *liltem=newQTreeWidgetitem(QStringList() << "力量")
- 添加根节点到树控件上
ui->treeWidget->addTopLevelltem(lltem);
- 添加子节点
liltem->addchild(l1);
// treeWidget树控件使用
// 设置水平头 QStringList使用匿名对象
ui->treeWidget->setHeaderLabels(QStringList() << "英雄" << "英雄介绍");
QTreeWidgetItem *liItem = new QTreeWidgetItem(QStringList() << "力量");
QTreeWidgetItem *minItem = new QTreeWidgetItem(QStringList() << "敏捷");
QTreeWidgetItem *zhiItem = new QTreeWidgetItem(QStringList() << "智力");
// 加载顶层的节点
ui->treeWidget->addTopLevelItem(liItem);
ui->treeWidget->addTopLevelItem(minItem);
ui->treeWidget->addTopLevelItem(zhiItem);
// 追加子节点
QStringList heroL1;
heroL1 << "刚被猪" << "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
QTreeWidgetItem *l1 = new QTreeWidgetItem(heroL1);
liItem->addChild(l1);
QTableWidget表格控件
- 设置列数
ui->tableWidget->setColumnCount(3);
- 设置水平表头
ui->tableWidget->setHorizontalHeaderLabels(QStringList() << "姓名" << "性别" << "年龄")
;
- 设置行数
ui->tableWidget->setRowCount(5);
- 设置正文
ui->tableWidget->setItem(0, 0, new QTableWidgetItem("雅思"));
// TableWidget 控件
// 设置列数
ui->tableWidget->setColumnCount(3);
// 设置水平表头
ui->tableWidget->setHorizontalHeaderLabels(QStringList() << "姓名" << "性别" << "年龄");
// 设置行数
ui->tableWidget->setRowCount(5);
// 设置正文
// ui->tableWidget->setItem(0, 0, new QTableWidgetItem("雅思"));
QStringList nameList;
nameList << "雅思" << "赵云" << "张飞" << "关羽" << "花木兰";
QStringList sexList;
sexList << "男" << "男" << "男" << "男" << "女";
for (int row = 0; row < 5; row++)
{
int col = 0;
ui->tableWidget->setItem(row, col++, new QTableWidgetItem(nameList[row]));
ui->tableWidget->setItem(row, col++, new QTableWidgetItem(sexList.at(row)));
// int 转 QString
ui->tableWidget->setItem(row, col++, new QTableWidgetItem(QString::number(row + 18)));
}
其他控件介绍
stackedWidget
栈控件ui->stackedWidget->setCurrentIndex(2);
- 下拉框
ui->comboBox->addItem("aaa");
Qlabel
显示图片ui->label->setPixmap(QPixmap(":/Image/a.png"));
QLabel
显示动图 gif图片ui->label_2->setMovie(movie);
movie->start();
#include "widget.h"
#include "./ui_widget.h"
#include <QMovie>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
// 栈控件使用
// 设置默认 定位scrollArea
ui->stackedWidget->setCurrentIndex(2);
// scrollArea按钮
connect(ui->btn_scrollArea, &QPushButton::clicked, [=] () {
ui->stackedWidget->setCurrentIndex(2);
});
// tooBox按钮
connect(ui->btn_toolBox, &QPushButton::clicked, [=] () {
ui->stackedWidget->setCurrentIndex(1);
});
// TabWidget按钮
connect(ui->btn_TabWidget, &QPushButton::clicked, [=] () {
ui->stackedWidget->setCurrentIndex(0);
});
// 下拉框
ui->comboBox->addItem("aaa");
ui->comboBox->addItem("bbb");
ui->comboBox->addItem("ccc");
// 点击按钮 选中拖拉机
connect(ui->btn_select, &QPushButton::clicked, [=] () {
//ui->comboBox->setCurrentIndex(2);
ui->comboBox->setCurrentText("ccc");
});
// 利用QLabel显示图片
ui->label->setPixmap(QPixmap(":/Image/a.png"));
// 利用QLabel显示 gif动态图片
QMovie *movie = new QMovie(":/Imgea/a.gif");
ui->label_2->setMovie(movie);
// 播放动图
movie->start();
}
Widget::~Widget()
{
delete ui;
}
自定义控件封装
- 添加新文件 Qt 设计师界面类
(.h .cpp .ui)
.ui
中设计QSpinBox
和Qslider
两个控件Widget
中使用自定义控件,拖拽一个Widget
,点击提升为,点击添加,点击提升- 实现功能,改变数字,滑动条跟着移动,信号槽监听。
- 提供
getNum
和setNum
对外接口 - 测试接口
关于Qt控件提升后找不到头文件的解决方法
-
CMake文件中添加头文件目录,在CMake中添加下面这段就可以解决了
-
INCLUDE_DIRECTORIES( ${PROJECT_SOURCE_DIR} )
// 在smallwidget.cpp中
#include "smallwidget.h"
#include "ui_smallwidget.h"
SmallWidget::SmallWidget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::SmallWidget)
{
ui->setupUi(this);
// QSpinBox移动 QSlider跟着移动
void(QSpinBox:: * spSignal) (int) = &QSpinBox::valueChanged;
connect(ui->spinBox, spSignal, ui->horizontalSlider, &QSlider::setValue);
// QSlider滑动 QSpinBox数字跟着改变
connect(ui->horizontalSlider, &QSlider::valueChanged, ui->spinBox, &QSpinBox::setValue);
}
SmallWidget::~SmallWidget()
{
delete ui;
}
void SmallWidget::setNum(int num)
{
ui->spinBox->setValue(num);
}
int SmallWidget::getNum()
{
return ui->spinBox->value();
}
// smallwidget.h
#ifndef SMALLWIDGET_H
#define SMALLWIDGET_H
#include <QWidget>
namespace Ui {
class SmallWidget;
}
class SmallWidget : public QWidget
{
Q_OBJECT
public:
explicit SmallWidget(QWidget *parent = nullptr);
~SmallWidget();
// 设置数字
void setNum(int);
// 获取数字
int getNum();
private:
Ui::SmallWidget *ui;
};
#endif // SMALLWIDGET_H
// smallwidget.ui
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>SmallWidget</class>
<widget class="QWidget" name="SmallWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>151</width>
<height>33</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QSpinBox" name="spinBox"/>
</item>
<item>
<widget class="QSlider" name="horizontalSlider">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
// widget.cpp
#include "widget.h"
#include "./ui_widget.h"
#include <QDebug>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
// 点击获取 获取当控件当前的值
connect(ui->btn_get, &QPushButton::clicked, [=](){
qDebug() << ui->widget->getNum();
});
// 设置一半
connect(ui->btn_set, &QPushButton::clicked, [=](){
ui->widget->setNum(50);
});
}
Widget::~Widget()
{
delete ui;
}
Qt中的事件
- 鼠标事件
- 鼠标进入事件
enterEvent
- 鼠标离开事件
leaveEvent
- 鼠标按下
mousePressEvent(QMouseEvent *ev)
- 鼠标释放
mouseReleaseEvent
- 鼠标移动
mouseMoveEvent
ev->x()
x坐标ev->y()
y坐标ev->button()
可以判断所有按键Qt::LeftButton
Ot::RightButton
ev->buttons()
判断组合按键 判断move
时候的左右键 结合&
操作符- 格式化字符串
QString(“%1 %2”).arg().arg()
// mylabel.h中
#ifndef MYLABEL_H
#define MYLABEL_H
#include <QLabel>
class myLabel : public QLabel
{
Q_OBJECT
public:
explicit myLabel(QWidget *parent = nullptr);
// 鼠标进入事件
//void enterEvent(QEnterEvent *event);
// 鼠标离开事件
//void leaveEvent(QEvent *event);
// 鼠标按下
virtual void mousePressEvent(QMouseEvent *ev);
// 鼠标释放
virtual void mouseReleaseEvent(QMouseEvent *ev);
// 鼠标移动
virtual void mouseMoveEvent(QMouseEvent *ev);
signals:
};
#endif // MYLABEL_H
// 在mylabel.cpp中
#include "mylabel.h"
#include <QDebug>
#include <QString>
#include <QMouseEvent>
myLabel::myLabel(QWidget *parent)
: QLabel{parent}
{
// 设置鼠标追踪状态
setMouseTracking(true);
}
// 鼠标进入事件
// void myLabel::enterEvent(QEnterEvent *event) {
// qDebug() << "鼠标进入了";
// }
// 鼠标离开事件
// void myLabel::leaveEvent(QEvent *event) {
// qDebug() << "鼠标离开了";
// }
// 鼠标按下
void myLabel::mousePressEvent(QMouseEvent *ev) {
if (ev->button() == Qt::LeftButton) {
QString str = QString("鼠标按下 x = %1 y = %2 global_x = %3 global_y = %4").arg(ev->x()).arg(ev->y()).arg(ev->globalX()).arg(ev->globalY());
qDebug() << str;
}
}
// 鼠标释放
void myLabel::mouseReleaseEvent(QMouseEvent *ev) {
if (ev->button() == Qt::LeftButton) {
QString str = QString("鼠标释放 x = %1 y = %2 global_x = %3 global_y = %4").arg(ev->x()).arg(ev->y()).arg(ev->globalX()).arg(ev->globalY());
qDebug() << str;
}
}
// 鼠标移动
void myLabel::mouseMoveEvent(QMouseEvent *ev) {
if (ev->buttons() & Qt::LeftButton) {
QString str = QString("鼠标移动 x = %1 y = %2 global_x = %3 global_y = %4").arg(ev->x()).arg(ev->y()).arg(ev->globalX()).arg(ev->globalY());
qDebug() << str;
}
}
定时器 1
- 利用事件
voidtimerEvent(QTimerEvent *ev)
- 启动定时器
startTimer(1000)
毫秒单位 timerEvent
的返回值是定时器的唯一标示 可以和ev->timerid
做比较
定时器 2
- 利用定时器类
QTimer
- 创建定时器对象
QTimer *timer = new QTimer(this)
- 启动定时器
timer->start(毫秒)
- 每隔一定毫秒,发送信号
timeout
,进行监听 - 暂停
timer->stop
// 在widget.h中
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
QT_BEGIN_NAMESPACE
namespace Ui {
class Widget;
}
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
// 重写定时器的事件
void timerEvent(QTimerEvent *e);
int id1; // 定时器1的唯一标识
int id2; // 定时器2的唯一标识
private:
Ui::Widget *ui;
};
#endif // WIDGET_H
// 在widget.cpp中
#include "widget.h"
#include "./ui_widget.h"
#include <QTimer>
#include <QPushButton>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
// 启动定时器
// 返回唯一ID
id1 = startTimer(1000); // 参数1 间隔 单位 毫秒
id2 = startTimer(2000);
// 定时器第二种方式
QTimer * timer = new QTimer(this);
// 启动定时器
timer->start(500);
connect(timer, &QTimer::timeout, [=](){
static int num = 1;
// label_4 每隔0.5秒 +1
ui->label_4->setText(QString::number(num++));
});
// 点击暂停按钮 实现停止定时器
connect(ui->pushButton, &QPushButton::clicked, [=](){
timer->stop();
});
}
Widget::~Widget()
{
delete ui;
}
void Widget::timerEvent(QTimerEvent *e) {
if (e->timerId() == id1) {
static int num1 = 1;
ui->label_2->setText(QString::number(num1++));
}
if (e->timerId() == id2) {
static int num2 = 1;
ui->label_3->setText(QString::number(num2++));
}
}
event事件
- 用途:用于事件的分发
- 也可以做拦截操作,不建议
bool event (QEvent *e);
- 返回值如果是
true
代表用户处理这个事件,不向下分发了 e->type() ==
鼠标按下
事件过滤器
- 在程序将时间分发到事件分发器前,可以利用过滤器做拦截
- 步骤
- 给控件安装事件过滤器
- 重写
eventFilter
函数(obj, ev)
// 在widget.h中
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
QT_BEGIN_NAMESPACE
namespace Ui {
class Widget;
}
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
// 重写定时器的事件
void timerEvent(QTimerEvent *e);
int id1;
int id2;
// 步骤2 重写 eventfilter事件
bool eventFilter(QObject *, QEvent *);
private:
Ui::Widget *ui;
};
#endif // WIDGET_H
// 在widget中
#include "widget.h"
#include "./ui_widget.h"
#include <QTimer>
#include <QPushButton>
#include <QMouseEvent>
#include <QDebug>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
// 启动定时器
// 返回唯一ID
id1 = startTimer(1000); // 参数1 间隔 单位 毫秒
id2 = startTimer(2000);
// 定时器第二种方式
QTimer * timer = new QTimer(this);
// 启动定时器
timer->start(500);
connect(timer, &QTimer::timeout, [=](){
static int num = 1;
// label_4 每隔0.5秒 +1
ui->label_4->setText(QString::number(num++));
});
// 点击暂停按钮 实现停止定时器
connect(ui->pushButton, &QPushButton::clicked, [=](){
timer->stop();
});
// 给label 安装事件过滤器
// 步骤1 安装事件过滤器
ui->label->installEventFilter(this);
// 步骤2 重写 eventfilter事件
}
Widget::~Widget()
{
delete ui;
}
void Widget::timerEvent(QTimerEvent *e) {
if (e->timerId() == id1) {
static int num1 = 1;
ui->label_2->setText(QString::number(num1++));
}
if (e->timerId() == id2) {
static int num2 = 1;
ui->label_3->setText(QString::number(num2++));
}
}
// 步骤2 重写 eventfilter事件
bool Widget::eventFilter(QObject *obj, QEvent *e) {
if (obj == ui->label) {
if (e->type() == QEvent::MouseButtonPress) {
QMouseEvent *ev = static_cast<QMouseEvent *>(e);
QString str = QString("事件过滤器中 鼠标按下 x = %1 y = %2 global_x = %3 global_y = %4").arg(ev->x()).arg(ev->y()).arg(ev->globalX()).arg(ev->globalY());
qDebug() << str;
return true; // true代表用户自己处理这个事件,不向下分发
}
}
// 其他默认处理
return QWidget::eventFilter(obj, e);
}
// 在mylabel.h中
#ifndef MYLABEL_H
#define MYLABEL_H
#include <QLabel>
class myLabel : public QLabel
{
Q_OBJECT
public:
explicit myLabel(QWidget *parent = nullptr);
// 鼠标进入事件
//void enterEvent(QEnterEvent *event);
// 鼠标离开事件
//void leaveEvent(QEvent *event);
// 鼠标按下
virtual void mousePressEvent(QMouseEvent *ev);
// 鼠标释放
virtual void mouseReleaseEvent(QMouseEvent *ev);
// 鼠标移动
virtual void mouseMoveEvent(QMouseEvent *ev);
// 通过event事件分发器 拦截器 鼠标按下事件
bool event(QEvent *e);
signals:
};
#endif // MYLABEL_H
// 在mylabel.cpp中
#include "mylabel.h"
#include <QDebug>
#include <QString>
#include <QMouseEvent>
#include <QLabel>
myLabel::myLabel(QWidget *parent)
: QLabel{parent}
{
// 设置鼠标追踪状态
setMouseTracking(true);
}
// 鼠标进入事件
// void myLabel::enterEvent(QEnterEvent *event) {
// qDebug() << "鼠标进入了";
// }
// 鼠标离开事件
// void myLabel::leaveEvent(QEvent *event) {
// qDebug() << "鼠标离开了";
// }
// 鼠标按下
void myLabel::mousePressEvent(QMouseEvent *ev) {
if (ev->button() == Qt::LeftButton) {
QString str = QString("鼠标按下 x = %1 y = %2 global_x = %3 global_y = %4").arg(ev->x()).arg(ev->y()).arg(ev->globalX()).arg(ev->globalY());
qDebug() << str;
}
}
// 鼠标释放
void myLabel::mouseReleaseEvent(QMouseEvent *ev) {
if (ev->button() == Qt::LeftButton) {
QString str = QString("鼠标释放 x = %1 y = %2 global_x = %3 global_y = %4").arg(ev->x()).arg(ev->y()).arg(ev->globalX()).arg(ev->globalY());
qDebug() << str;
}
}
// 鼠标移动
void myLabel::mouseMoveEvent(QMouseEvent *ev) {
if (ev->buttons() & Qt::LeftButton) {
QString str = QString("鼠标移动 x = %1 y = %2 global_x = %3 global_y = %4").arg(ev->x()).arg(ev->y()).arg(ev->globalX()).arg(ev->globalY());
qDebug() << str;
}
}
bool myLabel::event(QEvent *e) {
// 如果是鼠标按下,在event事件分发中拦截操作
if (e->type() == QEvent::MouseButtonPress) {
QMouseEvent *ev = static_cast<QMouseEvent *>(e);
QString str = QString("Event函数中 鼠标按下 x = %1 y = %2 global_x = %3 global_y = %4").arg(ev->x()).arg(ev->y()).arg(ev->globalX()).arg(ev->globalY());
qDebug() << str;
return true; // true代表用户自己处理这个事件,不向下分发
}
// 其他事件 交给父类处理 默认处理
return QLabel::event(e);
}
QPainter 绘图
-
绘图事件
void paintEvent()
-
声明一个画家对象
QPainter painter(this)
this
指定绘图设备 -
画线、画圆、画矩形、画文字
-
设置画笔
QPen
设置画笔宽度、风格 -
设置画刷
QBrush
设置画刷风格
QPainter高级设置
- 抗锯齿 效率低
painter.setRenderHint(QPainter::Antialiasing)
- 对画家进行移动
painter.translate(100,0);
- 保存状态
save
- 还原状态
restore
- 如果想手动调用绘图事件 利用
update
- 利用画家画图片
painter.drawPixmap(x, y, QPixmap(路径))
// 在widget.h中
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
QT_BEGIN_NAMESPACE
namespace Ui {
class Widget;
}
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
// 绘图事件
void paintEvent(QPaintEvent *);
int posX = 0;
private:
Ui::Widget *ui;
};
#endif // WIDGET_H
// 在widget.cpp中
#include "widget.h"
#include "./ui_widget.h"
#include <QPainter> // 画家类
#include <QPushButton>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
// 点击移动按钮 移动图片
connect(ui->pushButton, &QPushButton::clicked, [=](){
posX += 20;
// 如果要手动调用绘图事件 用update函数
update();
});
}
void Widget::paintEvent(QPaintEvent *) {
// // 实例化画家对象 this指定的是绘图设备
// QPainter painter(this);
// // 设置画笔
// QPen pen(QColor(255, 0, 0));
// // 设置画笔的宽度
// pen.setWidth(3);
// // 设置画笔风格
// pen.setStyle(Qt::DotLine);
// // 让画家 使用这个画笔
// painter.setPen(pen);
// // 设置画刷
// QBrush brush(Qt::cyan);
// // 设置画刷的风格
// brush.setStyle(Qt::Dense7Pattern);
// // 让画家使用这个画刷
// painter.setBrush(brush);
// // 画线
// painter.drawLine(QPoint(0, 0), QPoint(100, 100));
// // 画圆 椭圆
// painter.drawEllipse(QPoint(100, 100), 50, 50);
// // 画矩形
// painter.drawRect(QRect(0, 0, 100, 100));
// // 画文字
// painter.drawText(QRect(100, 100, 100, 50), "aaaaaaaaaaaaaaaaaaaaaa");
/* 高级设置 */
// QPainter painter(this);
// painter.drawEllipse(QPoint(100, 50), 50, 50);
// // 设置 抗锯齿能力 效率较低
// painter.setRenderHint(QPainter::Antialiasing);
// painter.drawEllipse(QPoint(200, 50), 50, 50);
// // 画矩形
// painter.drawRect(QRect(20, 20, 50, 50));
// // 移动画家
// painter.translate(100, 0);
// // 保存画家状态
// painter.save();
// painter.drawRect(QRect(20, 20, 50, 50));
// painter.translate(100, 0);
// // 还原画家保存状态
// painter.restore();
// painter.drawRect(QRect(20, 20, 50, 50));
/* 利用画家 画资源图片 */
QPainter painter(this);
// posX += 20;
// 如果超出屏幕 从0开始
if (posX > this->width()) {
posX = 0;
}
painter.drawPixmap(posX, 0, QPixmap(":/img/1.jpg"));
}
Widget::~Widget()
{
delete ui;
}
QPaintDevice绘图设备
QPixmap
Qlmage
QBitmap
(黑白色)QPicture
QWidget
QPixmap
对不同平台做了显示的优化QPixmap pix
(300,300)pix.fill
(填充颜色)- 利用画家 往 pix 上画画
QPainter painter(&pix)
- 保存
pix.save("路径")
QImage
可以对像素进行访问- 使用和
QPixmap
差不多Qlmage img(300, 300, Qlmage::Format_RGB32)
- 其他流程和
QPixmap
一样 - 可以对像素进行修改
img.setPixel(ijvalue);
- 使用和
QPicture
记录和重现 绘图指令QPicture pic
painter.begin(&pic);
- 保存
pic.save(任意后缀名)
- 重现 利用画家可以重现
painter.drawPicture(0,0,pic);
// 在Widget.h中
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
QT_BEGIN_NAMESPACE
namespace Ui {
class Widget;
}
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
// 绘图事件
void paintEvent(QPaintEvent *);
private:
Ui::Widget *ui;
};
#endif // WIDGET_H
// 在Widget.cpp中
#include "widget.h"
#include "./ui_widget.h"
#include <QPixmap>
#include <QPainter>
#include <QPicture>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
// // Pixmap绘图设备 专门为平台做了显示优化
// QPixmap pix(300, 300);
// // 填充颜色
// pix.fill(Qt::white);
// // 声明画家
// QPainter painter(&pix);
// painter.setPen(QPen(Qt::green));
// painter.drawEllipse(QPoint(150, 150), 100, 100);
// // 保存
// pix.save("C:\\Files\\Photos\\pix.png");
// QImage 绘图设备 可以对像素进行访问
// QImage img(300, 300, QImage::Format_RGB32);
// img.fill(Qt::white);
// // 声明画家
// QPainter painter(&img);
// painter.setPen(QPen(Qt::blue));
// painter.drawEllipse(QPoint(150, 150), 100, 100);
// // 保存
// img.save("C:\\Files\\Photos\\img.png");
// QPicture 绘图设备 可以记录和重现 绘图指令
QPicture pic;
QPainter painter;
painter.begin(&pic); // 开始往上pic上画
painter.setPen(QPen(Qt::cyan));
painter.drawEllipse(QPoint(150, 150), 100, 100);
painter.end(); // 结束画画
// 保存到磁盘
pic.save("C:\\Files\\Photos\\pic.cs");
}
// 绘图事件
void Widget::paintEvent(QPaintEvent *) {
// QPainter painter(this);
// // 利用Qimage 对像素进行修改
// QImage img;
// img.load(":/img/1.jpg");
// // 修改像素点
// for (int i = 50; i < 100; i++) {
// for (int j = 50; j < 100; j++) {
// QRgb value = qRgb(255, 0, 0);
// img.setPixel(i, j, value);
// }
// }
// painter.drawImage(0, 0, img);
QPainter painter(this);
// 重现QPicture的绘图指令
QPicture pic;
pic.load("C:\\Files\\Photos\\pic.cs");
painter.drawPicture(0, 0, pic);
}
Widget::~Widget()
{
delete ui;
}
QFile对文件进行读写操作10.1
QFile
进行读写操作QFile file(path文件路径)
- 读
file.open(打开方式)
QIODeviceBase::ReadOnly
- 全部读取
file.readAll()
按行读file.readLine()
atend()
判断是否读到文件尾 - 默认支持编码格式
utf-8
- 利用编码格式类指定格式
QTextCodeC
QTextCodec *codec = QTextCodecH::codecForName(gbk");
ui->textEdit->setText(codec->toUnicode(array));
- 文件对象关闭
close
- 写
file.open(QlODevice::writeOnly/Append)
file.write(内容)
fle.close
关闭
QFilelnfo读取文件信息
QFilelnfoinfo(路径)
qDebug() << "大小:" << info.size() << "后缀名:" << info.suffix() << "文件名称:" << info.fileName() << "文件路径:" << info.filePath(); qDebug() << "创建日期:" << info.birthTime().toString("yyyy/MM/dd hh:mm:ss"); qDebug() << "最后修改日期:" << info.lastModified().toString("yyyy-MM-dd hh:mm:ss");
// 在Widget.cpp中
#include "widget.h"
#include "./ui_widget.h"
#include <QFileDialog>
#include <QString>
#include <QFile>
#include <QStringConverter>
#include <QFileInfo>
#include <QDebug>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
// 点击选取文件按钮,弹出文件对话框
connect(ui->pushButton, &QPushButton::clicked, [=](){
QString path = QFileDialog::getOpenFileName(this, "打开文件", "C:\\Files\\Photos");
// 将路径放入到LineEdit中
ui->lineEdit->setText(path);
// 编码格式类
auto toUtf16 = QStringDecoder(QStringDecoder::Utf8);
// 读取内容 放入到 textEdit
// QFile默认支持的格式是 UTF-8
QFile file(path); // 参数就是读取文件的路径
// 设置打开方式
file.open(QIODeviceBase::ReadOnly);
// QByteArray array = file.readAll();
QByteArray array;
while (!file.atEnd()) {
array += file.readLine(); // 按行读
}
// 将读取到的数据 放入textEdit中
ui->textEdit->setText(array);
// 对文件对象进行关闭
file.close();
// 进行写文件
// file.open(QIODeviceBase::Append); // 用追加方式进行写
// file.write("啊啊啊啊啊啊啊啊啊");
// file.close();
// QFileInfo 文件信息类
QFileInfo info(path);
qDebug() << "大小:" << info.size()
<< "后缀名:" << info.suffix()
<< "文件名称:" << info.fileName()
<< "文件路径:" << info.filePath();
qDebug() << "创建日期:" << info.birthTime().toString("yyyy/MM/dd hh:mm:ss");
qDebug() << "最后修改日期:" << info.lastModified().toString("yyyy-MM-dd hh:mm:ss");
});
}
Widget::~Widget()
{
delete ui;
}
文章来源:https://blog.csdn.net/theRavensea/article/details/135113263
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!