文章目录
小技巧:
①.
或->
没提示的时候,一般是没包含头文件
② 函数查看帮助时,没有参数打不开帮助文档,在参数列表填写0x0
,按F1即可实现函数对应的文档查看。
1. 绘图
注意,更新窗口时
update
不能放在事件函数paintEvent
中,否则会死循环
绘图操作中不能有太复杂的运算,否则会很卡
背景图绘制、简单绘图及手动更新窗口
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = nullptr);
~Widget();
protected:
//重写绘图事件,虚函数
//如果在窗口绘图,必须放在绘图事件里实现
//绘图事件内部自动调用,窗口需要重绘的时候(状态改变)
void paintEvent(QPaintEvent *);
private slots:
void on_pushButton_clicked();
private:
Ui::Widget *ui;
int x;
};
#endif // WIDGET_H
widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include <QPainter>
#include <QPen>
#include <QBrush>
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
x = 0;
}
Widget::~Widget()
{
delete ui;
}
void Widget::paintEvent(QPaintEvent *)
{
//方式1:
//QPainter p(this);
//方式2:
QPainter p; //创建画家对象
p.begin(this);//指定当前窗口为绘图设备
//绘图操作,code
//p.drawxxxx();
//画背景图
// 方法1:
//p.drawPixmap(0,0,width(),height(),QPixmap("://Image/background.jpg"));
// 方法2:
p.drawPixmap(rect(),QPixmap("://Image/background.jpg"));
//定义画笔
QPen pen;
pen.setWidth(5);//设置线宽
//pen.setColor(Qt::red);//设置颜色
pen.setColor(QColor(14,9,234));//RGB颜色设置
pen.setStyle(Qt::DashLine);
//把画笔交给画家
p.setPen(pen);
//画直线
p.drawLine(50,50,150,50);
p.drawLine(50,50,50,150);
//创建画刷对象
QBrush brush;
brush.setColor(Qt::red);//设置颜色
brush.setStyle(Qt::Dense1Pattern);//设置样式
//把画刷交给画家
p.setBrush(brush);
//画矩形
p.drawRect(150,150,100,50);
//画圆
p.drawEllipse(QPoint(150,150),50,25);
//画笑脸
p.drawPixmap(x,180,80,80,QPixmap("://Image/11.png"));
p.end();
}
void Widget::on_pushButton_clicked()
{
x += 20;
if(x > width())
{
x = 0;
}
//刷新窗口,让窗口重绘
update();//间接调用paintEvent
}
QBitmap与QPixmap的区别
① QBitmap只有两种颜色:黑白
② QPixmap可画彩色图片
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = nullptr);
~Widget();
protected:
//重写绘图事件
//如果给窗口绘图,一定要在paintEvent()绘制
void paintEvent(QPaintEvent *);
private:
Ui::Widget *ui;
};
#endif // WIDGET_H
widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include <QPainter>
#include <QBitmap>
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
}
Widget::~Widget()
{
delete ui;
}
void Widget::paintEvent(QPaintEvent *)
{
QPainter p(this);
//QPixmap 图片背景透明
p.drawPixmap(0,0,QPixmap("://11.png"));
//QBitmap 图片背景透明
p.drawPixmap(200,0,QBitmap("://11.png"));
//QPixmap 图片背景白色
QPixmap pixmap;
pixmap.load("://11.png");
p.drawPixmap(0,220,pixmap);
//QBitmap 图片背景白色
QBitmap bitmap;
bitmap.load("://11.png");
p.drawPixmap(200,220,bitmap);
}
绘图设备
- QPixmap:最常用,针对屏幕进行优化了,和平台相关,不能对图片进行修改
widget.cpp#include "widget.h" #include "ui_widget.h" #include <QPainter> Widget::Widget(QWidget *parent) : QWidget(parent), ui(new Ui::Widget) { ui->setupUi(this); //绘图设备,400*300 QPixmap pixmap(400,300); QPainter p(&pixmap); //填充背景为白色 //法1:通过画家填充 //p.fillRect(0,0,400,300,QBrush(Qt::white)); //法2:通过绘图设备填充 pixmap.fill(Qt::white); p.drawPixmap(0,0,80,80,QPixmap(":/new/prefix1/11.png")); //保存图片 pixmap.save("../pixmap.png"); } Widget::~Widget() { delete ui; }
- QImage:和平台无关,可以对图片进行修改,可在线程中绘图
widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include <QPainter>
#include <QRgb>
#include <QImage>
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
//创建一个绘图设备,背景透明
QImage image(400,300,QImage::Format_ARGB32);
QPainter p;
p.begin(&image);
//绘图
p.drawImage(0,0,QImage("../11.png"));//项目上一层路径下
//对绘图设备前50个像素点进行操作,一般不会这么用
for(int i= 0;i < 50; i++)
{
for(int j=0;j<50;j++)
{
image.setPixel(QPoint(i,j), qRgb(0,255,0));
}
}
//注意,保存的时候是绘图设备保存
image.save("image.png");//注意,该路径是在项目build文件下
p.end();
}
Widget::~Widget()
{
delete ui;
}
- QPicture:保存绘图的状态(二进制文件)
注意:保存的是二进制文件,是图片的一种状态!
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = nullptr);
~Widget();
protected:
void paintEvent(QPaintEvent *);
private:
Ui::Widget *ui;
};
#endif // WIDGET_H
widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include <QPainter>
#include <QPicture>
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
QPicture picture;
QPainter p;
p.begin(&picture);
p.drawPixmap(0,0,80,80,QPixmap("../11.png"));
p.drawLine(50,50,150,50);
p.end();
//注意:保存的是二进制文件
picture.save("picture.png");
}
Widget::~Widget()
{
delete ui;
}
void Widget::paintEvent(QPaintEvent *)
{
QPicture pic;
pic.load("picture.png");//加载二进制文件
QPainter p(this);
p.drawPicture(0,0,pic);
}
- QImage和QPixmap相互转换
protected:
void paintEvent(QPaintEvent *);
widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include <QPainter>
#include <QPicture>
#include <QImage>
#include <QPixmap>
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
QPicture picture;
QPainter p;
p.begin(&picture);
p.drawPixmap(0,0,80,80,QPixmap("../11.png"));
p.drawLine(50,50,150,50);
p.end();
//注意:保存的是二进制文件
picture.save("picture.png");
}
Widget::~Widget()
{
delete ui;
}
void Widget::paintEvent(QPaintEvent *)
{
#if 0
QPicture pic;
pic.load("picture.png");//加载二进制文件
QPainter p(this);
p.drawPicture(0,0,pic);
#endif
QPainter p(this);
QPixmap pixmap;
pixmap.load("../11.png");
//QPixmap -> QImage
QImage tempImage = pixmap.toImage();
p.drawImage(0,0,tempImage);
QImage image;
image.load("../11.png");
//QImage -> QPixmap
QPixmap tempPixmap = QPixmap::fromImage(image);
p.drawPixmap(200,0,tempPixmap);
}
2. 不规则窗口
设置窗口为无边框图形
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = nullptr);
~Widget();
protected:
void paintEvent(QPaintEvent *);
private:
Ui::Widget *ui;
};
#endif // WIDGET_H
widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include <QPainter>
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
//去窗口边框
setWindowFlags(Qt::FramelessWindowHint | windowFlags());
//把窗口背景设置为透明
setAttribute(Qt::WA_TranslucentBackground);
}
Widget::~Widget()
{
delete ui;
}
void Widget::paintEvent(QPaintEvent *)
{
QPainter p(this);
p.drawPixmap(0,0,QPixmap("../11.png"));
}
鼠标移动不了,接下来写鼠标移动事件:
注意,移动的是窗口的左上角
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = nullptr);
~Widget();
protected:
void paintEvent(QPaintEvent *);
void mouseMoveEvent(QMouseEvent *e);
void mousePressEvent(QMouseEvent *e);
private:
Ui::Widget *ui;
QPoint p;
};
#endif // WIDGET_H
widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include <QPainter>
#include <QMouseEvent>
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
//去窗口边框
setWindowFlags(Qt::FramelessWindowHint | windowFlags());
//把窗口背景设置为透明
setAttribute(Qt::WA_TranslucentBackground);
}
Widget::~Widget()
{
delete ui;
}
void Widget::paintEvent(QPaintEvent *)
{
QPainter p(this);
p.drawPixmap(0,0,QPixmap("../11.png"));
}
void Widget::mousePressEvent(QMouseEvent *e)
{
if(e->button() == Qt::RightButton)
{
//如果是右键
close();
}
else if (e->button() == Qt::LeftButton)
{
//求座标差值
//当前点击座标-窗口左上角座标
p = e->globalPos() - this->frameGeometry().topLeft();
}
}
void Widget::mouseMoveEvent(QMouseEvent *e)
{
if(e->buttons() & Qt::LeftButton)
{
//move(e->globalPos());//注意,如果这么写,移动的时候有个偏距
move(e->globalPos() - p);
}
}
3.文件读写
- QBuffer
- QProcess
- QFileDevice
- QAbstractSocket
读文件
widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include <QFile>
#include <QFileDialog>
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
}
Widget::~Widget()
{
delete ui;
}
void Widget::on_buttonRead_clicked()
{
QString path = QFileDialog::getOpenFileName(this,
"open","../","TXT(*.txt)");
if(path.isEmpty() == false)
{
//文件对象
QFile file(path);
//打开文件,只读方式
bool isOk = file.open(QIODevice::ReadOnly);
if(isOk == true)
{
#if 0
//一次读完
//读文件,默认只识别utf8编码
QByteArray array = file.readAll();
//显示到编辑区
ui->textEdit->setText(QString(array));
#endif
QByteArray array;//Qt的数据处理中,字节数组用的非常多
while(file.atEnd() == false)
{
//读一行
array += file.readLine();
}
ui->textEdit->setText(array);
}
//关闭文件
file.close();
}
}
写文件
void Widget::on_buttonWrite_clicked()
{
QString path = QFileDialog::getSaveFileName(this,"save","../","TXT(*.txt)");
if(path.isEmpty() == false)
{
QFile file;//创建文件对象
//关联文件名字
file.setFileName(path);
//打开文件,只写方式
bool isOk = file.open(QIODevice::WriteOnly);
if(isOk == true)
{
//获取编辑区内容
QString str = ui->textEdit->toPlainText();
//写文件
//方法1:
//file.write(str.toUtf8());
//方法2:
//Qstring -> c++ string -> char *
//file.write(str.toStdString().data());
//转换成本地平台编码
file.write(str.toLocal8Bit());
}
//关闭文件
file.close();
}
}
QString、QByteArray、char *的相互转换
//QString -> QByteArray
QString buf = "123";
QByteArray a = buf.toUtf8();//中文
a = buf.toLocal8Bit();//本地编码
//QString -> QByteArray
QString buf = "123";
QByteArray a = buf.toUtf8();//中文
a = buf.toLocal8Bit();//本地编码
//QByteArray -> char *
char *b = a.data();
//char * -> QString
char *p = "abc";
QString c = QString(p);
QFileInfo获取文件信息
QString path = QFileDialog::getOpenFileName(this,
"open","../","TXT(*.txt)");
//获取文件信息
QFileInfo info(path);
qDebug() << "文件名称:" << info.fileName().toUtf8().data();
qDebug() << "文件后缀:" << info.suffix();
qDebug() << "文件大小:" << info.size();//单位字节
qDebug() << "文件创建时间:"<<info.created().toString("yyyy-MM-dd hh:mm:ss");
QDataStream读写文件
通过二进制读写文件
void Widget::writeData()
{
//创建文件对象
QFile file("../test.txt");
//打开文件,以只写方式打开
bool isOk = file.open(QIODevice::WriteOnly);
if(true == isOk)
{
//创建数据流,和file文件关联
//往数据流中输入数据,相当于往文件里写数据
QDataStream stream(&file);
//如果不转码,它会以二进制内容输出
//stream << QString("主要看气质").toLocal8Bit()<<250;
stream << QString("主要看气质")<<250;
file.close();
}
}
void Widget::readData()
{
//创建文件对象
QFile file("../test.txt");
//打开文件,以只写方式打开
bool isOk = file.open(QIODevice::ReadOnly);
if(true == isOk)
{
//创建数据流,和file文件关联
//从数据流中读数据,相当于从文件里读数据
QDataStream stream(&file);
//读的时候,按写的顺序去数据
QString str;
int a;
stream >> str >> a;
//qDebug() << str.toUtf8().data() << a;
cout << str.toUtf8().data() << a;
}
file.close();
}
QTextStream操作文件
通过文本方式操作,可以指定读写编码
widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include <QTextStream>
#include <QFile>
#include <QDebug>
#define cout qDebug() << "[" << __FILE__ <<":"<<__LINE__ <<"]"
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
writeData();
readData();
}
Widget::~Widget()
{
delete ui;
}
void Widget::writeData()
{
QFile file;
file.setFileName("../demo.txt");
bool isOk = file.open(QIODevice::WriteOnly);
if(true == isOk)
{
QTextStream stream(&file);
//指定编码
stream.setCodec("UTF-8");
stream <<QString("主要看气质")<<250;
file.close();
}
}
void Widget::readData()
{
QFile file;
file.setFileName("../demo.txt");
bool isOk = file.open(QIODevice::ReadOnly);
if(true == isOk)
{
QTextStream stream(&file);
//指定编码
stream.setCodec("UTF-8");
QString str;
int a;
// stream >> str >> a;
// cout << str.toUtf8().data() << a;
/*
* 以上这种方式,调试结果如下:
* [ ..\03day_10_QTextStream\widget.cpp : 54 ] 主要看气质250 0
* 发现,末尾多了一个0
*/
str = stream.readAll();
cout <<str;
file.close();
}
}
QBuffer
widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include <QBuffer>//内存文件
#include <QDebug>
#include <QDataStream>
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
QByteArray array;
QBuffer memFile(&array);//创建内存文件
memFile.open(QIODevice::WriteOnly);
memFile.write("1111");
memFile.write("2222");
memFile.write("3333");
memFile.close();
qDebug() << memFile.buffer();//输出时,三个字符串会连在一起,"111122223333"
qDebug() << "array" << array;
/*
* 以下这种取的方式更常用
*/
QBuffer memFile1;
memFile1.open(QIODevice::WriteOnly);
QDataStream stream(&memFile1);
stream <<QString("测试")<<250;
memFile1.close();
qDebug() << memFile1.buffer();
memFile1.open(QIODevice::ReadOnly);
QDataStream in;
in.setDevice(&memFile1);
QString str;
int a;
in >>str >>a;
memFile1.close();
qDebug() <<str.toUtf8().data()<<a;
}
Widget::~Widget()
{
delete ui;
}
小技巧
//方便调试用,输出文件名称和打印行号
#define cout qDebug() << "[" << __FILE__ <<":"<<__LINE__ <<"]"
//qDebug() << str.toUtf8().data() << a;
cout << str.toUtf8().data() << a;