文章目錄
小技巧:
①.
或->
沒提示的時候,一般是沒包含頭文件
② 函數查看幫助時,沒有參數打不開幫助文檔,在參數列表填寫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;