一、什么是QT:
QT是一个跨平台的C++图形用户界面应用程序框架。完全面向对象的。很容易扩展,并且允许真正的组件编程!
二、QT的优点:
- 跨平台。几乎支持所有的平台
- 接口简单容易上手
- 一定程度上简化了内存的回收机制
- 开发效率高,能够快速的构建应用程序
- 有很好的社区氛围
- 可以进行嵌入式开发
三、爱之初体验:
#include "QTone.h"
#include <QtWidgets/QApplication>//包含一个应用程序类的头文件
//argc命令行变量的数量 argv命令行变量的数组
int main(int argc, char *argv[])
{
//a应用程序对象中,有且仅有一个
QApplication a(argc, argv);
//窗口对象
QTone w;
//窗口对象默认不会显示,必须调用show方法显示窗口
w.show();
//让应用程序对象(a)进入消息循环
//让代码阻塞到这行
return a.exec();
}
. por文件解读:
QT += core gui //QT包含的模块
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets //大于4版本以上包含widget模块
命名规则:
类名:首字母大写,单词单词之间首字母大写
函数名 变量名称 :首字母小写,单词单词之间首字母大写
基础部分:
使用vs2019编程时出现中文乱码解决方案:
头文件中添加:#pragma execution_character_set("utf-8")
按钮空间常用API:
QPushButton* btn = new QPushButton;
//btn->show(); //show以顶层方式弹出窗口控件
btn->setParent(this);//让btn对象依赖在窗口中
btn->setText("第一个按钮"); //显示文本
//创建第二个按钮,按照控件的大小创建窗口
QPushButton* btn2 = new QPushButton("第二个按钮",this);
//移动btn2按钮
btn2->move(100, 100);
//调正按钮大小
btn2->resize(77, 77);
//重置窗口大小
resize(600,400);
//设置固定窗口大小
setFixedSize(600, 400);
//设置窗口标题
setWindowTitle("第一个窗口");
QT中的对象树:
当创建对象在堆区的时候,如果指定的父类是QObject派生下来的类或者QObject子类派生下来的类,可以不用管理释放的操作,该对象会放入到对象树种
一定程度上简化了内存的回收机制!
QT窗口坐标体系:
信号和槽:
语法:
connect(信号的发送者,发送的具体信号(signals),信号的接受者,信号的处理(槽(slots)))
信号槽的优点:松散耦合 信号发送端和接受端本身是没有关联的,通过connect链接将两端耦合在一起。
//创建第二个按钮,按照控件的大小创建窗口
QPushButton* btn2 = new QPushButton("第二个按钮",this);
//移动btn2按钮
btn2->move(100, 100);
//调正按钮大小
btn2->resize(77, 77);
//重置窗口大小
resize(600,400);
设置固定窗口大小
//setfixedsize(600, 400);
//设置窗口标题
setWindowTitle("第一个窗口");
//创建一个自己按钮对象
mypushbutton* mybtn = new mypushbutton;
mybtn->setText("我自己的按钮");
mybtn->move(200, 0);
mybtn->setParent(this);
mybtn->resize(100, 100);
setFixedSize(600, 400);
//需求 点击我的按钮关闭窗口
connect(mybtn,&mypushbutton::clicked,this,&QTone::close);
connect(btn2, &QPushButton::clicked, this, &QWidget::close);
自定义信号和槽:
自定义信号:写到signals下
1、返回值void
2、需要声明不需要实现
3、可以有参数
自定义槽:写到public slot下或者public下或者全局下都可以
1、返回void
2、需要声明也需要实现
3、可以有参数可以重载
当自定义信号和槽出现重载,需要明确指向函数的地址
Qstring转成char *:先用.ToUtf8()转成OByteArray
再用.Data()转为char *
信号可以链接信号,断开信号的时候用disconnect,一个信号可以连接多个槽函数
多个信号可以连接同一个槽函数 ,信号和槽函数的参数必须类型一一对应,信号的参数个数可以多于槽函数的参数个数
了解Lambda表达式:
[capture](parameters)mutable->return-type
{
statement
}
mutable用于修饰值传递的变量,修改的是拷贝而不是本体
[]标识符 里面放=是值传递,&则是引用传递
()参数 {}实现体
返回值:[]()->type{}
窗口跳转小作业:
#include "test01.h"
#include <QWidget>
#include <QPushButton>
test01::test01(QWidget* parent)
: QWidget(parent), ui(new Ui::test01Class)
{
ui->setupUi(this);
QWidget* newD = new QWidget;
QPushButton *btn1 = new QPushButton;
QPushButton *btn2 = new QPushButton;
btn1->setText("开机按钮");
btn2->setText("关机按钮");
this->resize(700, 700);
newD->resize(700, 700);
btn1->move(200, 200);
btn2->move(200, 500);
btn1->setParent(this);
btn2->setParent(this);
setWindowTitle("第一次窗口小作业");
connect(btn1, &QPushButton::clicked, newD, &QWidget::show);
connect(btn2, &QPushButton::clicked, newD, [=]() {
if (btn2->text() == "关机按钮")
{
btn1->close();
newD->close();
btn2->setText("开机按钮");
}
else
{
btn1->show();
btn2->setText("关机按钮");
}
});
}
test01::~test01()
{
delete ui;
}
QMainWindow:
QMainWindow是一个为用户提供主窗口程序的,包含一个菜单栏、多个工具栏、多个错接部件、一个状态栏以及一个中心部件。是许多应用程序的基础
第一节:
#include "Mainwindow.h"
#include<qmenu.h>
#include<qtoolbar.h>
#include<qpushbutton.h>
Mainwindow::Mainwindow(QWidget *parent)
: QMainWindow(parent)
{
resize(600, 400);
//菜单栏的创建 菜单栏最多只能有一个
QMenuBar* bar = menuBar();
//将菜单栏放在窗口之中
setMenuBar(bar);
//生成菜单栏控件
QMenu *fileMenu = bar->addMenu("文件");
QMenu *editMenu = bar->addMenu("编辑");
//创建菜单项
QAction *newAction = fileMenu->addAction("新建");
QAction *newAction2 = editMenu->addAction("查找");
//添加分割线
fileMenu->addSeparator();
QAction* openAction = fileMenu->addAction("打开");
//工具栏 可以有多个
QToolBar* toolBar = new QToolBar(this);
//设置左停靠
addToolBar(Qt::TopToolBarArea,toolBar);
//后期设置 只允许左右停靠
toolBar->setAllowedAreas(Qt::LeftToolBarArea | Qt::RightToolBarArea);
//设置浮动
toolBar->setFloatable(false);
/* 设置移动
toolBar->setMovable(false);*/
//工具栏中设置内容
toolBar->addAction(newAction);
toolBar->addAction(openAction);
//工具栏中添加控件
QPushButton* btn = new QPushButton("aa", this);
toolBar->addWidget(btn);
}
Mainwindow::~Mainwindow()
{
}
第二节:
Mainwindow::Mainwindow(QWidget *parent)
: QMainWindow(parent)
{
resize(600, 600);
//状态栏 最多有一个
QStatusBar* stBar = statusBar();
//设置到窗口中
setStatusBar(stBar);
//放标签控件
QLabel* label = new QLabel("提示信息",this);
stBar->addWidget(label);
QLabel* label1 = new QLabel("右侧提示提示信息",this);
stBar->addPermanentWidget(label1);
//铆接部件(浮动窗口) 可以有多个
QDockWidget* dockWidget = new QDockWidget("浮动",this);
addDockWidget(Qt::BottomDockWidgetArea, dockWidget);
//设置后期停靠区域,只允许上下
dockWidget->setAllowedAreas(Qt::TopDockWidgetArea | Qt::BottomDockWidgetArea);
//设置中心部件 只能有一个
QTextEdit* edit = new QTextEdit(this);
setCentralWidget(edit);
}
对话框创建:
test01::test01(QWidget *parent)
: QMainWindow(parent)
{
ui->setupUi(this);
//点击新建按钮弹出对话框
connect(ui->actionnew, &QAction::triggered, [=]() {
//对话框 分类
//模态对话框(不可以对其他窗口进行操作) 非模态对话框(可以对其他窗口进行操作)
//模态创建 阻塞
//QDialog dlg(this);
模态的方式进行创建
//dlg.resize(200, 200);
//dlg.exec();
//qDebug() << "对话框弹出了";
//非模态对话框
QDialog* dla2 = new QDialog(this);
dla2->resize(200, 200);
//非模态创建
dla2->show();
//55号 属性(帮助文档)
dla2->setAttribute(Qt::WA_DeleteOnClose);
qDebug() << "非模态对话框弹出了";
}
);
}
为了防止一闪而过才开辟到堆区
标准对话框:
{
ui->setupUi(this);
//消息对话框
//错误对话框
//QMessageBox::critical(this, "crtical", "错误");
//信息对话框
//QMessageBox::information(this, "info", "信息");
//提问对话框
//参数3 显示内容 参数4 关联按键类型 参数5 默认关联回车按键
//QMessageBox::question(this, "quew", "提问", QMessageBox::Save | QMessageBox::Cancel, QMessageBox::Cancel);
//警告对话框
QMessageBox::warning(this, "warning", "警告");
}
其他标准对话框:
ui->setupUi(this);
//颜色对话框
QColor color = QColorDialog::getColor(QColor(255, 0, 0));
//文件对话框
//打开文件对话框
//参数3 默认打开路径 参数4 过滤文件格式
//返回值是选取的路径
QString str = QFileDialog::getOpenFileName(this, "打开文件", "F:\\777","(*.txt)");
//字体对话框
bool flag;
QFont font = QFontDialog::getFont(&flag, QFont("华文彩云", 36));
QListWidget 列表容器:
QListWidgetitem 一行内容
ui->setupUi(this);
//利用listwidget写实
QListWidgetItem* item = new QListWidgetItem("锄禾日当午");
//将一行诗放入到listwidget控件钟
ui->listWidget->addItem(item);
item->setTextAlignment(Qt::AlignHCenter);
QStringList //QList<string> qt风格的字符串链表
QStringList list;
list << "锄禾日当午" << "汗滴禾下土" << "谁知盘中餐"<<"粒粒皆辛苦";
ui->listWidget->addItems(list);
QTreeWidget 树控件:
ui->setupUi(this);
//设置水平头
ui->treeWidget->resize(500, 500);
ui->treeWidget->setHeaderLabels(QStringList() << "英雄" << "英雄介绍");
QTreeWidgetItem* item = new QTreeWidgetItem(QStringList() << "力量");
QTreeWidgetItem* minitem = new QTreeWidgetItem(QStringList() << "明捷");
QTreeWidgetItem* zhiitem = new QTreeWidgetItem(QStringList() << "智力");
ui->treeWidget->addTopLevelItem(item);
ui->treeWidget->addTopLevelItem(minitem);
ui->treeWidget->addTopLevelItem(zhiitem);
//追加子节点
QStringList heroL1;
QStringList minL1;
QStringList zhiL1;
heroL1 << "刚被猪" << "肉盾";
minL1 << "智力拉满";
zhiL1 << "打错了上面是敏捷";
QTreeWidgetItem* l1 = new QTreeWidgetItem(heroL1);
QTreeWidgetItem* l2 = new QTreeWidgetItem(minL1);
QTreeWidgetItem* l3 = new QTreeWidgetItem(zhiL1);
item->addChild(l1);
minitem->addChild(l2);
zhiitem->addChild(l3);
QTableWidget表格控件:
speach::speach(QWidget *parent)
: QMainWindow(parent)
{
ui->setupUi(this);
//设置列数
ui->tableone->setColumnCount(3);
//设置水平表头
ui->tableone->setHorizontalHeaderLabels(QStringList() << "姓名" << "性别" << "年龄");
//设置行数
ui->tableone->setRowCount(5);
ui->tableone->resize(500, 500);
//设置正文
//ui->tableone->setItem(0, 0, new QTableWidgetItem("亚瑟"));
QStringList nameList;
nameList << "亚瑟" << "赵云" << "张飞" << "关羽" << "花木兰";
QList<QString>sexList;
sexList << "男" << "男" << "男" << "男" << "女";
for (int i = 0; i < 5;++i)
{
int col = 0;
ui->tableone->setItem(i, col++, new QTableWidgetItem(nameList[i]));
ui->tableone->setItem(i, col++, new QTableWidgetItem(sexList[i]));
ui->tableone->setItem(i, col++, new QTableWidgetItem(QString::number(i+18)));
}
}
封装一个进度条滑动:
{
//进度条滑动
ui->setupUi(this);
void(QSpinBox:: * spSignal)(int) = &QSpinBox::valueChanged;
connect(ui->kongjian, spSignal, ui->jindutiao, &QSlider::setValue);
connect(ui->jindutiao, &QSlider::valueChanged, ui->kongjian, &QSpinBox::setValue);
}
鼠标事件:
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
}
void Widget::mousePressEvent(QMouseEvent *ev)
{
if(ev->button() == Qt::LeftButton)
{
qDebug() << " 鼠标进入了 ";
}
}
void Widget::mouseReleaseEvent(QMouseEvent *ev)
{
if(ev->button() == Qt::LeftButton)
{
qDebug() << " 鼠标离开了 ";
}
}
void Widget::mouseMoveEvent(QMouseEvent *ev)
{
if(ev->buttons() & Qt::LeftButton)
{
qDebug() << " 鼠标移动了 ";
}
}
写一个定时器:
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
i = startTimer(1000);
j = startTimer(2000);
}
void Widget::timerEvent(QTimerEvent * ev)
{
if(ev->timerId() == i)
{
static int num = 1;
ui->label_1->setNum(num++);
}
if(ev->timerId() == j)
{
static int num2 = 1;
ui->label->setNum(num2++);
}
}
另一种写法:
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
QTimer * timer = new QTimer(this);
timer->start(500);
connect(timer,&QTimer::timeout,[=]()
{
static int num = 1;
ui->label_1->setText(QString::number(num++));
});
connect(ui->stop_btn,&QPushButton::clicked,[=]()
{
timer->stop();
});
}
event事件分发:
返回值为true代表用户自己处理事件
void mylabel::mousePressEvent(QMouseEvent *ev)
{
QString str = QString("我按压了");
qDebug() <<str;
}
void mylabel::mouseReleaseEvent(QMouseEvent *ev)
{
qDebug() <<"离开";
}
void mylabel::mouseMoveEvent(QMouseEvent *ev)
{
qDebug() <<"移动";
}
bool mylabel::event(QEvent *e)
{
if(e->type() == QMouseEvent::MouseButtonPress)
{
QString str = QString("event按压了");
qDebug() <<str;
return true; //代表用户自己处理这个事件
}
return QLabel::event(e); //其他事件交给父类处理
}
程序将事件分发到事件分发器之前,可以用过滤器做拦截:
//安装事件过滤器
ui->label->installEventFilter(this);
//重写eventFilter
}
bool Widget::eventFilter(QObject *o,QEvent *e)
{
if(o == ui->label)
{
if(e->type() == QEvent::MouseButtonPress)
{
QString str = QString("事件过滤器");
qDebug() <<str;
return true;
}
}
return QWidget::eventFilter(o,e);
}
QPainter绘图事件:
主文件中定义void paintEvent(QPaintEvent *);
void Widget::paintEvent(QPaintEvent *)
{
QPainter painter(this); //this指定绘图设备
//设置画笔
QPen pen(QColor(255,0,0));
//设置画笔宽度
pen.setWidth(3);
//设置风格
pen.setStyle(Qt::DotLine);
//设置画刷
//QBrush brush(QColor(0,255,0));
QBrush brush(Qt::cyan);
//画刷风格
brush.setStyle(Qt::Dense7Pattern);
//画家使用画刷
painter.setBrush(brush);
//让画家使用这支笔
painter.setPen(pen);
//画线
painter.drawLine(QPoint(0,0),QPoint(77,77));
//画圆 (椭圆)
painter.drawEllipse(QPoint(100,100),50,50);
//画矩形
painter.drawRect(QRect(20,20,77,77));
//画文字
painter.drawText(QRect(10,200,150,50),"hello worldddddd");
}
QPainter绘图事件高级设置:
void Widget::paintEvent(QPaintEvent *)
{
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));
}
绘图设备:
#include "widget.h"
#include "ui_widget.h"
#include<QPixmap>
#include<QPainter>
#include<QImage>
#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(100,50),100,100);
// //保存
// pix.save("E:\\pix.png");
// QImage 可以对像素进行访问
// QImage img(300,300,QImage::Format_RGB32);
// img.fill(Qt::white);
// QPainter painter(&img);
// painter.setPen(QPen(Qt::green));
// painter.drawEllipse(QPoint(100,50),100,100);
// img.save("E:\\pix.png");
//QPicture 绘图设备 记录和重现绘图指令
QPicture pic;
QPainter painter;
painter.begin(&pic); //开始在pic中画
painter.setPen(QPen(Qt::red));
painter.drawEllipse(QPoint(100,50),100,100);
painter.end();
pic.save("E:\\pic.zt");
}
void Widget::paintEvent(QPaintEvent *event)
{
QPainter painter;
//重现 QPicture
QPicture pic;
pic.load("E:\\pic.zt");
painter.drawPicture(0,0,pic);
}
Widget::~Widget()
{
delete ui;
}
QFile对文件进行读写:
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
connect(ui->pushButton,&QPushButton::clicked,[=]()
{
QString path = QFileDialog::getOpenFileName(this,"打开文件","F:\\QT\\QTfile\\test03");
//将路径放入到lineEdit中
ui->lineEdit->setText(path);
//读取内容 放入到textEdit中
//QFile 默认支持的方式是utf-8
QFile file(path); //参数就是文件的路径
//打开方式
file.open(QIODevice::ReadOnly);
QByteArray array = file.readAll();
//读取的数据放入textEdit中
ui->textEdit->setText(array);
});
}
其他编码格式:
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
connect(ui->pushButton,&QPushButton::clicked,[=]()
{
QString path = QFileDialog::getOpenFileName(this,"打开文件","F:\\QT\\QTfile\\test03");
//将路径放入到lineEdit中
ui->lineEdit->setText(path);
//编码的格式类
QTextCodec * codec = QTextCodec::codecForName("qbk");
//读取内容 放入到textEdit中
//QFile 默认支持的方式是utf-8
QFile file(path); //参数就是文件的路径
//打开方式
file.open(QIODevice::ReadOnly);
QByteArray array = file.readAll();
//更改编码格式
ui->textEdit->setText(codec->toUnicode(array));
});
}
文件信息获取:
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
QString path = QFileDialog::getOpenFileName(this,"打开文件","F:\\QT\\QTfile\\test03");
//QFileinfo 文件信息类
QFileInfo info(path);
qDebug() <<"大小 : "<<info.size()<<"后缀名: " <<info.suffix()<<"文件名 : "<<info.fileName();
qDebug() <<"创建日期"<<info.created().toString("yyyy/MM/dd hh:mm:ss");
//最后修改日期 info.lastModified()
}