QT笔记(节选)具体图片等下载资源
根据b站视频做的笔记:
https://www.bilibili.com/video/BV1g4411H78N?p=44&spm_id_from=pageDriver&vd_source=a3e6a48ccd3d7d1f969f662653ed68c9
qt是一个跨平台的c++图形用户界面应用程序框架,界面引擎。
下载地址:
https://www.qt.io/download-open-source
https://download.qt.io/
优点:
1.跨平台
2.接口简单,容易上手
3.一定程度上简化了内存回收
成功案例:
谷歌地图,多媒体播放器
程序规范
命名规范:
1.类名:首字母大写,单词和单词之间收字母大写
2.函数名\变量名:首字母小写,单词和单词之间首字母大写
快捷键:
1.注释:ctrl+ /
2.运行:ctrl + r
3.编译:ctrl + b
4.字体缩放: ctrl + 鼠标滚轮
5.查找:ctrl + f
6.帮助文档: f1
7.自动对齐:ctrl + i
8.同名之间的.h和.cpp之间切换:f4
创建一个qt程序(QWidget)
1.点击新建程序:
2.选择正确的项目创建
qmake和cmake两者都用来构建系统,都生成一个Makefile,该文件由make读取以构建项目,告诉编译器和链接器该做什么,以创建可执行文件(或动态或静态库)。
qmake专注于使用Qt的项目,QtCreator可以轻松生成项目文件(适合初学者),并由QtCreator支持;CMake用于广泛的项目,支持多种平台和语言,受多个IDE支持:例如QtCreator,Visual Studio,生成多个IDE的项目描述,包含简化Qt使用的命令(最重要:automoc)。如果项目使用Qt,则最好使用qmake。 CMake更通用,几乎适合任何类型的项目。
如果项目使用Qt,但又不想使用qmake,则必须自己做一些事情:运行元对象编译器(MOC),包含路径(告诉编译器在哪里寻找Qt标头),链接(告诉链接器在哪里寻找Qt库)。
QWidget是窗口函数,是QMainWindow和QDialog的父类。
QMainWindow和QDialog比QWidget包含更多功能函数
如果此处没有可选的kit,是因为安装qt时默认没有安装这些组件。需要卸载重装,重装时勾选相应的组件。
git是用于多版本控制,可以用于多人开发。
用户a使用git push命令推送写的代码到线上,用户b可以通过git pull命令将a的代码拉取到本地做二次开发,达到协作开发的目的。
git相关命令可以查看这个博文:
https://blog.csdn.net/Eoneanyna/article/details/134971873?spm=1001.2014.3001.5501
创建成功后的文件目录:
//main.cpp
#include <QApplication>//包含一个应用程序类的头文件
#include "widget.h"
//main程序入口,argc命令变量的数量,argv命令行变量的数组
int main(int argc, char *argv[])
{
//应用程序对象,在qt中,应用程序对象有且只有一个
QApplication a(argc, argv);
QTranslator translator;
const QStringList uiLanguages = QLocale::system().uiLanguages();
for (const QString &locale : uiLanguages) {
const QString baseName = "gold_" + QLocale(locale).name();
if (translator.load(":/i18n/" + baseName)) {
a.installTranslator(&translator);
break;
}
}
//窗口对象 widget的父类-》QWidget
Widget w;
//窗口对象显示。默认不会显示,必须调用show方法显示窗口
w.show();
//让应用程序对象进入消息循环
/*
while(true){
if(点击×){
break;
}
}
*/
return a.exec();
}
//widget.h
#ifndef WIDGET_H
#define WIDGET_H
//ifndef跟#pragma once一样的意思,
//如果不存在头文件名则定义一个
#include <QWidget>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
private:
Ui::Widget *ui;
};
#endif // WIDGET_H
## 程序.pro文件
#qt包含的模块 gui图形模块
QT += core gui
#大于4版本以上,包含widget模块
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
CONFIG += c++11
# You can make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
#指定生成的目标应用程序名称,如test.exe
#TARGET = test
#TEMPLATE = app//模板 应用程序模板 application
#lib -建立一个库的makefile
#vcapp -建立一个应用程序的vs项目文件
#vclib -建立一个库的vs项目文件
#subdirs -这是一个特殊的模板,它可以创建一个能够进入特定目录并为一个项目文件生成makefile,并调用make的makefile
#源文件
SOURCES += \
main.cpp \
widget.cpp
#头文件
HEADERS += \
widget.h
#
FORMS += \
widget.ui
TRANSLATIONS += \
gold_zh_CN.ts
CONFIG += lrelease
CONFIG += embed_translations
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
其中:
QT += core gui
qt有以下的模块:
在帮助文档中,有对应的类属于哪个模块的说明,如:
创建一个按钮
//widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include<QPushButton>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
//创建一个按钮
QPushButton * btn = new QPushButton;
//让按钮对象在父框图内
btn->setParent(this);
//按钮显示的文本
btn->setText("这是按钮");
//创建第二个按钮,按照控件的大小创建窗口
QPushButton * btn1 = new QPushButton("button2",this);
//移动btn1的位置
//x以右为正方向
//y以下为正方向
btn1->move(100,100);
//重置窗口的大小
resize(600,400);
ui->setupUi(this);
}
Widget::~Widget()
{
delete ui;
}
效果:
按钮文本设置报错
按钮设置文本时报错,发现是中文太长了,删除几个字之后就可以正常跑了。
中文乱码解决
设置文本为UTF-8
点击 工具-》》选项
按钮重新指定大小
//重新设置btn1的大小
btn1->resize(200,70);
设置窗口标题
//设置窗口标题
setWindowTitle("翻金");
窗口标题设置失败
这是由于 ui->setupUi(this);这一行
设置了ui界面的一些默认规则。
可以将标题代码放到这一行后面,或者注释掉这一行都可以。
效果:
点击按钮关闭窗图
connect(信号的发送者,发送的具体信号,信号的接收者,信号的处理(槽函数))
槽函数的优点:松散的耦合,信号发送端和接收端通过connect连接在一起
//实际使用
//创建第二个按钮,按照控件的大小创建窗口
QPushButton * btn1 = new QPushButton("button2",this);
//如果发射者与接收者属于同一个对象的话,那么在 connect 调用中接收者参数可以省略。
connect(btn1,&QPushButton::clicked,this,&Widget::close);
//或者
//connect(btn1,&QPushButton::clicked,this,&QWidget::close);
自定义的信号和槽
信号关键字
signals:
自定义信号,写到signals下 返回值是void,只需要定义声明,不需要实现。 可以有参数,可以重载
槽函数关键字:
slots:
- public slots:在这个区内声明的槽意味着任何对象都可将信号与之相连接。这对于组件编程非常有用,你可以创建彼此互不了解的对象,将它们的信号与槽进行连接以便信息能够正确的传递。
- protected slots:在这个区内声明的槽意味着当前类及其子类可以将信号与之相连接。这适用于那些槽,它们是类实现的一部分,但是其界面接口却面向外部。
- private slots:在这个区内声明的槽意味着只有类自己可以将信号与之相连接。这适用于联系非常紧密的类。
注意:
一个信号可以连接多个槽函数
多个信号可以连接同一个槽函数
绑定的信号和槽函数的参数类型必须对应;信号的参数个数可以多于槽函数的参数个数,但不可以少于槽函数的参数个数
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
private:
Ui::Widget *ui;
signals:
void hungry();
void hungry(int);
public:
//早期的qt版本必须写public slots
//高级版本可以写到public下
//返回值void ,需要声明,需要实现
//可以有参数,可以重载
void treat();
};
//发出信号
emit this->hungry();
//
connect()
connect的使用
connect可以对信号进行关联
//如:
connect( aButton, SIGNAL(clicked()), SIGNAL(aSignal()) );
//当信号 clicked() 被发射时,信号 aSignal() 也接着被发射。
//第三个参数,接受者是this时,可以被省略
当槽发生重载时:
//连接带参数的信号和槽
void(Widget:: *hungrySignal)(int) = &Widget::hungry;
void(Widget:: *treatFunc)(int) = &Widget::treat;
connect(this,hungrySignal,this,treatFunc);
disconnect取消关联
当信号与槽没有必要继续保持关联时,我们可以使用 disconnect 函数来断开连接。其定义如下:
bool QObject::disconnect ( const QObject * sender, const char * signal,
const Object * receiver, const char * member ) [static]
在 disconnect 函数中 0 可以用作一个通配符,分别表示任何信号、任何接收对象、接收对象中的任何槽函数。但是发射者 sender 不能为 0,其它三个参数的值可以等于 0。
1、断开与某个对象相关联的任何对象。这似乎有点不可理解,事实上,当我们在某个对象中定义了一个或者多个信号,这些信号与另外若干个对象中的槽相关联,如果我们要切断这些关联的话,就可以利用这个方法,非常之简洁。
disconnect( myObject, 0, 0, 0 )
或者
myObject->disconnect()
2、断开与某个特定信号的任何关联。
disconnect( myObject, SIGNAL(mySignal()), 0, 0 )
或者
myObject->disconnect( SIGNAL(mySignal()) )
3、断开两个对象之间的关联。
disconnect( myObject, 0, myReceiver, 0 )
或者
myObject->disconnect( myReceiver )
emit 关键字
Newspaper类的send()函数比较简单,只有一个语句emit newPaper(m_name);。emit 是 Qt 对 C++ 的扩展,是一个关键字(其实也是一个宏)。emit 的含义是发出,也就是发出newPaper()信号。感兴趣的接收者会关注这个信号,可能还需要知道是哪份报纸发出的信号?所以,我们将实际的报纸名字m_name当做参数传给这个信号。当接收者连接这个信号时,就可以通过槽函数获得实际值。这样就完成了数据从发出者到接收者的一个转移。
void Widget::sing(){
//发出信号
emit this->hungry(1);
}
qt4之前的信号和槽连接方式
connect(this,SIGNAL(hungry()),this,SLOT(treat()));
//qt4的优点:参数直观
//缺点:类型不做检测,编译时不会做错误检查
//底层SINGNAL("hungry") SLOT("treat") 用函数名去查找
对象树
在上一节的按钮中new的对象无须释放,是因为按钮的父类Qobject是以对象树的形式组织起来的。
在创建QObject对象在堆区时,会自动添加到其父对象的children()列表。当父对象析构的时候,这个列表中所有对象也会被析构(注意,这里的父对象并不是继承意义上的父类)
//创建一个按钮
QPushButton * btn = new QPushButton;
//让按钮对象在父框图内
btn->setParent(this);
//这句就是设置btn的按钮有this这个父对象
Lambda表达式(匿名函数)
c++11中的lambda表达式用于定义并创建匿名的函数对象
,以简化编程工作
[函数对象参数](操作符重载函数参数)mutable->返回值{
函数体
}
函数对象参数:标志一个lambda的开始,不能省略
-
空
。没有使用任何函数对象参数 -
=
函数体内可以使用lambda所在作用范围内所有可见的局部变量(报考lambda所在类的this),并且是值传递方式 -
&
:函数体内可以使用Lambda所在作用范围内所有可见的局部变量 -
this
:可以使用lambda所在类中的成员变量 -
a
:将变量a按值进行传递,函数体内不能修改传递进来的a值,因为默认情况下函数是const的,要修改传递进来的a的拷贝,可以添加mutable
修饰符[m]()mutable{ m=10; };
-
&a
:变量a的引用 -
a,&b
,a按值进行传递,b按引用进行传递 -
=,&a,&b
除ab按引用进行传递外,其他参数按照值进行传递 -
&,a,b
除ab按照值传递外,其他参数按照引用进行传递
有返回值的匿名函数
int ret = []()->int{
return 100;
};
课外小demo
写一个匿名槽函数,点击open变按钮为close,点击close变为open
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
//创建一个按钮
QPushButton * btn = new QPushButton;
//让按钮对象在父框图内
btn->setParent(this);
//按钮显示的文本
btn->setText("open");
connect(btn,&QPushButton::clicked,this,[=](){
if(btn->text() == (QString)"open"){
btn->setText("close");
}else{
btn->setText("open");
}
});
}
写一个匿名槽函数,点击open打开第二个窗口,点击close关闭第二个窗口
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
//创建一个按钮
QPushButton * btn = new QPushButton;
//让按钮对象在父框图内
btn->setParent(this);
//按钮显示的文本
btn->setText("open");
QPushButton * Nbtn = new QPushButton;
connect(btn,&QPushButton::clicked,this,[=](){
if(btn->text() == (QString)"open"){
Nbtn->show();
btn->setText("close");
}else{
btn->setText("open");
Nbtn->close();
}
});
}
QMainWindow
QmainWindow是一个为用户提供主窗口程序的类,包含菜单栏,工具栏、多个链接部件、一个状态栏以及一个中心部件。是许多应用程序的基础,如文本编辑器,图片编辑器等
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QToolBar>
#include<QPushButton>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
//重置窗口大小
resize(600,400);
//菜单栏创建,最多只能有一个
QMenuBar *bar = menuBar();
//把菜单栏放入窗口
setMenuBar(bar);
//添加菜单栏内容
//创建菜单
QMenu *fileMenu = bar->addMenu("文件");
QMenu *editMenu = bar->addMenu("编辑");
//创建菜单项
QAction * newAction = fileMenu->addAction("新建");
//添加分割线
fileMenu->addSeparator();
fileMenu->addAction("打开");
//工具栏,可以有多个
QToolBar *toolBar = new QToolBar(this);
addToolBar(Qt::LeftToolBarArea,toolBar);
//设置只允许左右停靠
toolBar->setAllowedAreas(Qt::LeftToolBarArea|Qt::RightToolBarArea);
//设置工具栏浮动,默认是开启的现在设置关闭
toolBar->setFloatable(false);
//设置工具栏移动(总开关)
toolBar->setMovable(false);
//工具栏中设置内容
toolBar->addAction("钢笔");
//添加分割线
toolBar->addSeparator();
//在工具栏中设置菜单栏的内容
toolBar->addAction(newAction);
//在工具栏中添加按钮的控件
QPushButton *btn = new QPushButton("按钮",this);
toolBar->addWidget(btn);
}
MainWindow::~MainWindow()
{
delete ui;
}
效果:
添加状态栏、浮动窗口、中心编辑器
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QToolBar>
#include<QPushButton>
#include<QLabel>
#include<QDockWidget>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
//重置窗口大小
resize(600,400);
//菜单栏创建,最多只能有一个
QMenuBar *bar = menuBar();
//把菜单栏放入窗口
setMenuBar(bar);
//添加菜单栏内容
//创建菜单
QMenu *fileMenu = bar->addMenu("文件");
QMenu *editMenu = bar->addMenu("编辑");
//创建菜单项
QAction * newAction = fileMenu->addAction("新建");
//添加分割线
fileMenu->addSeparator();
fileMenu->addAction("打开");
//工具栏,可以有多个
QToolBar *toolBar = new QToolBar(this);
addToolBar(Qt::LeftToolBarArea,toolBar);
//设置只允许左右停靠
toolBar->setAllowedAreas(Qt::LeftToolBarArea|Qt::RightToolBarArea);
//设置工具栏浮动,默认是开启的现在设置关闭
toolBar->setFloatable(false);
//设置工具栏移动(总开关)
toolBar->setMovable(false);
//工具栏中设置内容
toolBar->addAction("钢笔");
//添加分割线
toolBar->addSeparator();
//在工具栏中设置菜单栏的内容
toolBar->addAction(newAction);
//在工具栏中添加按钮的控件
QPushButton *btn = new QPushButton("按钮",this);
toolBar->addWidget(btn);
//状态栏,最多有一个
QStatusBar *stBar = statusBar();
//设置到窗口中
setStatusBar(stBar);
//放标签控件(默认左侧)
QLabel *label = new QLabel("提示信息",this);
stBar->addWidget(label);
//右侧存放
QLabel *rightLabel = new QLabel("右侧",this);
stBar->addPermanentWidget(rightLabel);
//铆接部件(浮动窗口)可以有多个
QDockWidget *dW = new QDockWidget("浮动",this);
addDockWidget(Qt::LeftDockWidgetArea,dW);
//设置中心部件(文本编辑器)
QTextEdit *edit = new QTextEdit(this);
setCentralWidget(edit);
}
MainWindow::~MainWindow()
{
delete ui;
}
添加资源文件
设计窗图
ui界面直接添加控件,设计窗图
添加资源文件并引用
鼠标右键->add new添加新文件
ui->setupUi(this);
// ui->actionnew->setIcon(QIcon("C:\Users\26479\Pictures\20140210195808_XtEQF.jpeg"));
//添加qt资源":+前缀名+文件名"
//actionopen这个空间名是在ui界面就添加的,如下图
ui->actionopen->setIcon(QIcon(":/new/prefix1/icon"));
效果:
模态和非模态对话框
模态对话框
:不可以对其他窗口进行操作,会阻塞
非模态对话框
:可以对其他窗口进行操作
//头文件
#include<QDialog>
//模态创建
QDialog dlg(this);
dlg.exec();
//非模态对话框
QDialog *dlg2 = new QDialog(this);
dlg2->show();
//在此处匿名对象创建的堆内存由于主窗图没有释放,堆内存也不会释放
//因此可以手动设置一下,关闭对话框则释放内存
connect(ui->actionopen,&QAction::triggered,[=](){
//模态创建
QDialog dlg(this);
dlg.exec();
//非模态对话框
QDialog *dlg2 = new QDialog(this);
//关闭时,释放堆内存
dlg2->setAttribute(Qt::WA_DeleteOnClose);
dlg2->show();
});
其他标准对话框
例子:
消息对话框
文件对话框
返回值是选取的路径
打开txt类型的文件
ui布局
在右边窗图上,选择相应的多个控件,设置水平/垂直布局,和弹簧可以使窗图无论怎么拉都不变形。
选择左边的控件,将其拖动到中间的ui里面即可添加
多加点弹簧,使账号密码空间处于窗图最中间
可以设置窗图的最大最小值,以免缩放太小,导致看不清
先设置用户名的文本大小
再设置密码的文本大小
按钮也可以添加图片
按钮组
单选按钮
选择按钮(单选)
但此时如果增加两个选择按钮为:已婚、未婚
则加上男、女四个选项只能选其一项。
但真实效果想要男/女,已婚/未婚。此时就可以用到按钮组
将成组的按钮拖入同一个group box,即可实现
有三个组件层次:第一个层次是一个widget,其中包含两个按钮组(第二层),水平布局
第二个层次为两个按钮组,每个按钮组(第三层)为垂直布局。
设置默认选项
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
//设置单选按钮,男默认选择(男的按钮名称为radioButton)
ui->radioButton->setChecked(true);
}
MainWindow::~MainWindow()
{
delete ui;
}
多选按钮
//设置多选按钮,2是选中 0是未选择
connect(ui->checkBox,&QCheckBox::stateChanged,[=](int state){
qDebug() << state;
});
listWidget
列表容器
QStringList list;
list << "锄禾"<<"悯农";
ui->listWidget->addItems(list);
设置文本居中方式
QListWidgetItem *item = new QListWidgetItem("悯农");
ui->listWidget->addItem(item);
item->setTextAlignment(Qt::AlignHCenter);
树控件
tree Widget
//设置水平头
ui->treeWidget->setHeaderLabels(QStringList()<<"英雄"<<"介绍");
QTreeWidgetItem *tItem = new QTreeWidgetItem(QStringList()<<"力量");
//加载顶层结点
ui->treeWidget->addTopLevelItem(tItem);
//追加子结点
QTreeWidgetItem *tCItem = new QTreeWidgetItem(QStringList()<<"力量1");
tItem->addChild(tCItem);
表格控件
//设置列数
ui->tableWidget->setColumnCount(3);
//设置水平表头
ui->tableWidget->setHorizontalHeaderLabels(QStringList()<<"姓名"<<"年龄");
//设置行数
ui->tableWidget->setRowCount(3);
//设置正文(0,0)位置,设置张三
ui->tableWidget->setItem(0,0,new QTableWidgetItem("张三"));
Qlabel图片显示
图片和动图的显示:
自定义控件
新建一个自定义控件:
绑定并新建类:
在新建的ui中设计好自定义的控件:
在主页面中使用这个自定义的控件:
效果:
自定义控件中的两个控件相互绑定:
//Qspinbox移动,Qslider跟着移动
void(QSpinBox::*spSignal)(int) = &QSpinBox::valueChanged;
connect(ui->spinBox,spSignal,ui->verticalSlider,&QSlider::setValue);
//Qslider移动,Qspinbox跟着移动
void(QSlider::*slSignal)(int) = &QSlider::valueChanged;
connect(ui->verticalSlider,slSignal,ui->spinBox,&QSpinBox::setValue);
鼠标事件
可以在窗口类中重写相应的鼠标事件的实现,进行相应逻辑处理。
常用的事件:
1.鼠标进入控件
2.鼠标离开控件
3.鼠标按下
4.鼠标释放
如:实现函数
鼠标输出光标位置:
注意输出的格式
跟printf差不多
这里的x,y是在控件内的xy 如果要获取主界面的坐标则需要使用获取函数globalX(),globalY()
鼠标键左右同时按下
如果要判断是否左右鼠标键都同时按下,可结合&操作符
鼠标追踪
设置鼠标追踪:
如果鼠标追踪不设置,只有在鼠标点击这个控件的时候,才能调用实现的鼠标事件逻辑;而当设置了鼠标追踪则可以不用点击,也可以调用鼠标事件的逻辑。
定时器(QTimer)
重写定时器事件
//类定义.h
#ifndef VOICE_H
#define VOICE_H
#include <QWidget>
#include <QTimerEvent>
namespace Ui {
class voice;
}
class voice : public QWidget
{
Q_OBJECT
public:
explicit voice(QWidget *parent = nullptr);
~voice();
void timerEvent(QTimerEvent *);
private:
Ui::voice *ui;
};
#endif // VOICE_H
#include "voice.h"
#include "ui_voice.h"
#include<QGroupBox>
#include<QTimerEvent>
#include<QDebug>
voice::voice(QWidget *parent) :
QWidget(parent),
ui(new Ui::voice)
{
ui->setupUi(this);
//开启定时器
startTimer(1000);//单位毫秒 1000毫秒=1秒
}
void voice::timerEvent(QTimerEvent *){
//加static,num不是局部变量不会重复声明
static int num = 1;
qDebug() << (QString::number(num++));
}
voice::~voice()
{
delete ui;
}
效果
两个定时器
定时器都有唯一的timeId,可以通过判断timeId的方式来判断定时器。
voice::voice(QWidget *parent) :
QWidget(parent),
ui(new Ui::voice)
{ //开启定时器 int id1
//int id2作为成员变量
this->id1 = startTimer(1000);//单位毫秒 1000毫秒=1秒
//开启定时器
this->id2 = startTimer(2000);//单位毫秒 2000毫秒=2秒
}
void voice::timerEvent(QTimerEvent *te){
//加static,num不是局部变量不会重复声明
if (te->timerId() == id1){
static int num = 1;
qDebug() << (QString::number(num++));
}
if (te->timerId() == id2){
static int num2 = 1;
qDebug() << (QString::number(num2++));
}
}
信号和槽方式(推荐)
QTimer * timer = new QTimer(this);
//启动定时器
timer->start(500);
//绑定信号和槽
connect(timer,&QTimer::timeout,[=](){
static int num = 1;
qDebug() << (QString::number(num++));
});
暂停定时器
QTimer * timer = new QTimer(this);
//启动定时器
timer->start(500);
//绑定信号和槽
connect(timer,&QTimer::timeout,[=](){
static int num = 1;
qDebug() << (QString::number(num++));
});
//暂停定时器
timer->stop();
事件分发器
绘图事件
//在widget中重写函数
void painEvent(QPaintEvent *);
void paint::painEvent(QPaintEvent *){
//实例化画家对象
QPainter painter(this);
//设置画笔
QPen pen(QColor(255,0,0));
//设置画笔宽度
pen.setWidth(3);
//让画家使用这个笔
painter.setPen(pen);
//设置画刷
QBrush brush(Qt::cyan);
//让画家使用画刷
painter.setBrush(brush);
//指定两个点,画一条线
painter.drawLine(QPoint(0,0),QPoint(100,100));
//画圆,圆心(100,100),横半径50,竖半径50,横半径!=竖半径时画的是椭圆
painter.drawEllipse(QPoint(100,100),50,50);
//画矩形,从(20,20)作为左顶点开始画一个长宽为50的正方形
painter.drawRect(QRect(20,20,50,50));
//画文字从(20,20)作为左顶点开始画一个长宽为50的正方形,并往这个矩形里面放"文字"两个字
painter.drawText(QRect(20,20,50,50),"文字");
}
高级设置
抗锯齿
用于保证图片清晰度
效率比较低
//实例化画家对象
QPainter painter(this);
//开启抗锯齿
painter.setRenderHint(QPainter::Antialiasing);
移动(0,0)到某位置
//移动(0,0)位置
painter.translate(100,0);
恢复设置
//还原设置
painter.restore();
画图片
//画图片
painter.drawPixmap(20,100,QPixmap("./image.png"));
更新图片:
//画图片
int x;
painter.drawPixmap(x,100,QPixmap("./image.png"));
//如果要手动调用绘图事件,用update更新
x = 20;
update();
qt的绘图系统实际上是,使用Qpainter在QPainterDevice上进行绘制,他们之间使用QPaintEngine进行通讯(也就是翻译Qpainter的部分指令)
绘图设备是指继承QPainterDevice的子类,qt一共提供了四个这样的类
- QPixmap:专门为图像在屏幕上的显示做了优化
- QBitmap:是QPixmap的一个子类,色深限定为1,可以使用QPixmap的IsQBitmap()函数来判断是不是QBitmap
- QImage:专门为图像的像素级访问做了优化(可以修改像素点)
- QPicture:可以记录和重现QPainter的各项指令
//声明绘图设备
QPixmap pix(300,300);
//背景填充白色
pix.fill(Qt::white);
//声明画家
QPainter painter1(&pix);
//画图
painter1.drawPixmap(x,100,QPixmap("./image.png"));
//保存图片
pix.save("./save.png");
QImage
像素点修改
//声明绘图设备
QImage img;
//加载图片
img.load("./image.png");
//修改像素点
for(int i = 30;i<100;i++){
for(int j = 50;j<100;i++){
QRgb value = qRgb(255,0,0);
img.setPixel(i,j,value);
}
}
//声明画家
QPainter painter2(this);
//画图
painter2.drawImage(0,0,img);
//保存图片
pix.save("./save.png");
QPicture
#include<QPicture>
void paint::painEvent(QPaintEvent *){
//QPicture
QPicture pic3;
QPainter painter3;
//开始往pic上画
painter3.begin(&pic3);
painter3.drawEllipse(QPoint(150,150),100,100);
//结束画画
painter3.end();
//保存图片
pic3.save("./test.zt");
//重现QPicture的绘图指令
QPainter painter4(this);
QPicture pic4;
pic4.load("./test.zt");
painter4.drawPicture(0,0,pic4);
}
文件读写(QFile)
读文件
打开文件路径
#include<QFileDialog>
QFileDialog::getOpenFileName(this,"打开文件","C:\\Users");
读取文本
默认支持utf-8
//获取文件路径
QString str = QFileDialog::getOpenFileName(this,"打开文件","C:\\Users");
//读取内容
QFile file(str);
//设置打开方式,只读
file.open(QIODevice::ReadOnly);
//读取到所有文本
QByteArray array = file.readAll();
//可以把array放入文本 setText(array)
file.close();
格式编码设置:
#include<QTextCodec>
file::file(QWidget *parent) : QWidget(parent)
{
//获取文件路径
QString str = QFileDialog::getOpenFileName(this,"打开文件","C:\\Users");
//读取内容
QFile file(str);
//设置打开方式,只读
file.open(QIODevice::ReadOnly);
//读取到所有文本
QByteArray array = file.readAll();
//可以把array放入文本 setText(array)
QTextCodec *codec = QTextCodec::codecForName("gbk");
codec->toUnicode(array);
// ui->textEdit->setText(codec->toUnicode(array))
file.close();
}
按行读取
file::file(QWidget *parent) : QWidget(parent)
{
//获取文件路径
QString str = QFileDialog::getOpenFileName(this,"打开文件","C:\\Users");
//读取内容
QFile file(str);
//设置打开方式,只读
file.open(QIODevice::ReadOnly);
QByteArray array;
//读到文件尾
while(!file.atEnd()){
//按行读取
array += file.readLine();
}
//文件关闭
file.close();
}
写文件
//追加方式进行写
file.open(QIODevice::Append);
file.write("aaaa");
file.close();
文件信息读取
QFileInfo类
有文件的信息属性获取,例如:
1.path:前缀名(suffix())、后缀名
2.大小: size()
3.创建日期:created()
4.最后修改日期:lastModifed()
`c++
//获取文件路径
QString str = QFileDialog::getOpenFileName(this,“打开文件”,“C:\Users”);
//读取内容
QFile file(str);
//设置打开方式,只读
file.open(QIODevice::ReadOnly);
//读取到所有文本
QByteArray array = file.readAll();
//可以把array放入文本 setText(array)
file.close();
格式编码设置:
```c++
#include<QTextCodec>
file::file(QWidget *parent) : QWidget(parent)
{
//获取文件路径
QString str = QFileDialog::getOpenFileName(this,"打开文件","C:\\Users");
//读取内容
QFile file(str);
//设置打开方式,只读
file.open(QIODevice::ReadOnly);
//读取到所有文本
QByteArray array = file.readAll();
//可以把array放入文本 setText(array)
QTextCodec *codec = QTextCodec::codecForName("gbk");
codec->toUnicode(array);
// ui->textEdit->setText(codec->toUnicode(array))
file.close();
}
按行读取
file::file(QWidget *parent) : QWidget(parent)
{
//获取文件路径
QString str = QFileDialog::getOpenFileName(this,"打开文件","C:\\Users");
//读取内容
QFile file(str);
//设置打开方式,只读
file.open(QIODevice::ReadOnly);
QByteArray array;
//读到文件尾
while(!file.atEnd()){
//按行读取
array += file.readLine();
}
//文件关闭
file.close();
}
写文件
//追加方式进行写
file.open(QIODevice::Append);
file.write("aaaa");
file.close();
文件信息读取
QFileInfo类
有文件的信息属性获取,例如:
1.path:前缀名(suffix())、后缀名
2.大小: size()
3.创建日期:created()
4.最后修改日期:lastModifed()