日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Qt学习之Qt基础入门(下)

發布時間:2025/3/15 编程问答 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Qt学习之Qt基础入门(下) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1. 前言

前兩篇博客簡單的闡述了一下Qt的入門用法,這篇博客繼續跟著視頻學習。

Qt入門系列:
Qt學習之C++基礎
Qt學習之Qt安裝
Qt學習之Qt基礎入門(上)
Qt學習之Qt基礎入門(中)
Qt學習之Qt基礎入門(下)

本文原創,創作不易,轉載請注明!!!
本文鏈接
個人博客: https://ronglin.fun/archives/222
PDF鏈接:見博客網站
CSDN: https://blog.csdn.net/RongLin02/article/details/120668605

2. 自定義控件封裝

有時候,我們希望一個控件是我們自己的設計的,比如將一個Label和進度條結合起來作為一個整體來使用
我們將一個Widget面板中加入自己設計好的控件,然后將面板作為 一個整體插入總ui中。
一個自定義功能:
設計兩個按鈕,為 開啟–關閉 互補 狀態,當點擊開始按鈕時,關閉按鈕可用,開始按鈕不可點擊,當點擊關閉按鈕時,開啟按鈕可用,關閉按鈕不可點擊

2.1. 創建一個ui


然后就是選擇基類,因為我們是在Widget面板上進行自定義,所以就選擇Widget
然后就是自定義的類,取名叫做SwitchButtonWidget

然后下一步,完成就行了
之后會生成三個文件,一個是ui文件,然后就是類的.h .cpp文件。
我們先在ui界面設計控件,我這里就是兩個按鍵,然后用了垂直布局,同時調整Widget面板大小

然后就在類中設計其邏輯功能,當點擊開始按鈕時,關閉按鈕變成可用,開始按鈕變得不可點擊,當點擊關閉按鈕時,狀態相反。
在文件switchbuttonwidget.cpp中

#include "switchbuttonwidget.h" #include "ui_switchbuttonwidget.h"SwitchButtonWidget::SwitchButtonWidget(QWidget *parent) :QWidget(parent),ui(new Ui::SwitchButtonWidget) {ui->setupUi(this);ui->pushButton_2->setEnabled(false); //關閉按鈕默認不可用//當點擊開始按鈕的時候connect(ui->pushButton,&QPushButton::clicked,[=](){ui->pushButton->setEnabled(false); //關閉按鈕設置可用ui->pushButton_2->setEnabled(true); //開始按鈕設置不可用});//當點擊關閉按鈕的時候connect(ui->pushButton_2,&QPushButton::clicked,[=](){ui->pushButton->setEnabled(true); //關閉按鈕設置不可用ui->pushButton_2->setEnabled(false); //開始按鈕設置可用}); }SwitchButtonWidget::~SwitchButtonWidget() {delete ui; }

到此,自定義的控件設計完畢

2.2. 運用自定義控件

設計完畢,就要在主ui中應用控件
因為我們的自定義控件的基類是Widget,所以我們在主ui中,拖入一個Widget面板,作為我們自定義框架的區域
然后 右鍵 -> 提升為

然后我們將這個普通的widget提升為我們自己自定義的控件面板,所以說提升的類名稱就是剛才定義好的SwitchButtonWidget類,這里注意大小寫,.h文件全是小寫的,而類名是大小寫都有的,然后全局包含,全局包含勾選的話就是以后用到這個自定義控件的時候可以直接使用,因為我們這里只用一次,就不勾選了

然后,點擊 添加 ,然后點擊 提升
之后雖然在ui中看不出來,但是在右側,widget類已經變成SwitchButtonWidget類了,這就說明已經提升成功,運行查看結果

效果和預期一樣,應用成功,只有一點不太方便的是,當提升之后,主ui中只是顯示一個框框,不顯示自定義控件的內容

3. Qt中的事件

事件和Java中類似,當用戶對程序互交的時候,就會產生很多事件,例如點擊鼠標,鍵盤輸入,改變窗口大小等等

3.1. 鼠標事件

鼠標進入事件 enterEvent
鼠標離開事件 leaveEvent
鼠標按下 mousePressEvent ( QMouseEvent event)
鼠標釋放 mouseReleaseEvent
鼠標移動 mouseMoveEvent
設置鼠標追蹤方法:setMouseTracking(true);
同時在事件中封裝了事件的狀態,比如獲取鼠標移動的坐標

event->x(); //x坐標 event->y(); //y坐標

而且也可以判斷左右鍵,比如

if(event->button() == Qt::LeftButton) {qDebug() << "點擊了鼠標左鍵"; } else if(event->button() == Qt::RightButton) {qDebug() << "點擊了鼠標右鍵"; }

同時,還有一個buttons方法可以同時判斷多個,用法稍有不同

if(event->buttons() & Qt::LeftButton ) {qDebug() << "點擊了鼠標左鍵"; }

可以用event->buttons()判斷組合按鍵 判斷move時候的左右鍵,要結合 & 操作符

小tips:
格式化字符串用法:QString( "%1 %2 ").arg( 111 ).arg(222);

3.2. event事件

在一些常用事件的上邊還有一個層event事件,實現事件分發,返回值是bool,如果返回是true就代表用戶要處理這個事件,不在向下分發。
函數原型是

bool event( QEvent * ev);

主要用于事件的分發,也可以做攔截操作,但是不建議,用法如下:

bool MyWidget::event(QEvent *e) {//如果是鼠標按下 ,在event事件分發中做攔截操作if(e->type() == QEvent::MouseButtonPress){QMouseEvent * ev = static_cast<QMouseEvent *>(e);QString str = QString( "Event函數中::鼠標按下了 x = %1 y = %2 globalX = %3 globalY = %4 " ).arg(ev->x()).arg(ev->y()).arg(ev->globalX()).arg(ev->globalY());qDebug() << str;return true; //true代表用戶自己處理這個事件,不向下分發}//其他事件 交給父類處理 默認處理return QLabel::event(e); }

事件過濾器
同時在event之上還有一個事件過濾器,也可以做攔截,要重寫eventfilter函數
在程序將時間分發到事件分發器前,可以利用過濾器做攔截
步驟
1、給控件安裝事件過濾器

ui->label->installEventFilter(this);

2、重寫 eventFilter函數 (obj , ev)

bool MyWidget::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 globalX = %3 globalY = %4 " ).arg(ev->x()).arg(ev->y()).arg(ev->globalX()).arg(ev->globalY());qDebug() << str;return true; //true代表用戶自己處理這個事件,不向下分發}}//其他默認處理return QWidget::eventFilter(obj,e); }

關系如下圖:

4. 定時器

定時器是一個很常用的用法,比如3s后關閉窗口等等
定時器有兩種用法

4.1. 時間事件

3.1 利用事件 void timerEvent ( QTimerEvent * ev)
3.2 啟動定時器 startTimer( 1000) 毫秒單位
3.3 timerEvent 的返回值是定時器的唯一標示 可以和ev->timerId 做比較

用法如下:
在.h文件的public下,先定義要重寫定時器的事件,然后如果要有多個定時器,也要指定標識,例如這里有兩個

public:explicit Widget(QWidget *parent = 0);~Widget();//重寫定時器的事件void timerEvent(QTimerEvent *);int id1; //定時器1的唯一標示int id2; //定時器2的唯一標示

然后在.cpp文件中,先初始化定時器標識,比如是要1s還是2s,然后在timerEvent中判斷即可

#include "widget.h" #include "ui_widget.h" #include <QDebug> Widget::Widget(QWidget *parent) :QWidget(parent),ui(new Ui::Widget) {ui->setupUi(this);//啟動定時器id1 = startTimer(1000); //參數1 間隔 單位 毫秒id2 = startTimer(2000); }void Widget::timerEvent(QTimerEvent * ev) {if(ev->timerId() == id1){static int num = 1;//label2 每隔1秒+1ui->label_2->setText( QString::number(num++));}if(ev->timerId() == id2){//label3 每隔2秒 +1static int num2 = 1;ui->label_3->setText( QString::number(num2++));} }Widget::~Widget() {delete ui; }

4.2. QTimer

只在一個事件中寫多個定時器實在不方便,所以Qt提供了一個QTimer定時器類
利用定時器類 QTimer
創建定時器對象 QTimer * timer = new QTimer(this)
啟動定時器 timer->start(毫秒)
每隔一定毫秒,發送信號 timeout ,進行監聽
暫停 timer->stop
用法如下,用connect函數,當定時器到時間時要執行的操作

//定時器第二種方式QTimer * timer = new QTimer(this);//啟動定時器timer->start(500);connect(timer,&QTimer::timeout,[=](){static int num = 1;//label4 每隔0.5秒+1ui->label_4->setText(QString::number(num++));});//點擊暫停按鈕 實現停止定時器connect(ui->btn,&QPushButton::clicked,[=](){timer->stop();});

5. 畫圖

5.1. QPainter 繪圖

繪圖事件 void paintEvent()
聲明一個畫家對象 QPainter painter(this) this指定繪圖設備
可以畫線、畫圓、畫矩形、畫文字
設置畫筆 QPen 設置畫筆寬度 、風格,設置畫刷 QBrush 設置畫刷 風格
直接看代碼用法,需要注意的時,如果需要重畫的時候,調用update();即可,就能重畫paintEvent內的內容
有關具體 用法可查詢API

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(20,20,50,50)); //畫矩形painter.drawText(QRect(10,200,150,50) , "好好學習,天天向上"); //畫文字}

5.2. QPainter高級設置

抗鋸齒 效率低

painter.setRenderHint(QPainter::Antialiasing);

對畫家進行移動
painter.translate(100,0);
保存狀態 save
還原狀態 restore
如果想手動調用繪圖事件 利用update
利用畫家畫圖片 painter.drawPixmap( x,y,QPixmap( 路飛) )
用法見下,不再仔細說明

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));/利用畫家 畫資源圖片 /// // QPainter painter(this); // QPixmap pix = QPixmap(":/Image/Luffy.png"); // //如果超出屏幕 從0開始 // if(posX >= this->width()) // { // posX = -pix.width(); // } // painter.drawPixmap(posX,0,pix);}

5.3. QPaintDevice繪圖設備

QPixmap QImage QBitmap(黑白色) QPicture QWidget
有關繪圖設備這里不過多說明,API中有詳細的說明

5.3.1. QPixmap

QPixmap 對不同平臺做了顯示的優化
QPixmap pix( 300,300) pix.fill( 填充顏色 )
利用畫家 往pix上畫畫 QPainter painter( & pix)
保存 pix.save( “路徑”)

5.3.2. Qimage

Qimage 可以對像素進行訪問
使用和QPixmap差不多 QImage img(300,300,QImage::Format_RGB32);
其他流程和QPixmap一樣
可以對像素進行修改 img.setPixel(i,j,value);

5.3.3. QPicture

QPicture 記錄和重現 繪圖指令
QPicture pic
painter.begin(&pic);
保存 pic.save( 任意后綴名 )
重現 利用畫家可以重現painter.drawPicture(0,0,pic);

6. 文件操作

文件操作十分常見了,Qt的文件操作和C++的類似,十分簡便,不像Java文件操作復雜

6.1. QFile

對文件進行讀寫操作
QFile進行讀寫操作
QFile file( path 文件路徑)

6.1.1. 讀

file.open(打開方式) QIODevice::readOnly
全部讀取 file.readAll() 按行讀 file.readLine() atend()判斷是否讀到文件尾
認支持編碼格式 utf-8
利用編碼格式類 指定格式 QTextCodeC
QTextCodec * codec = QTextCodec::codecForName(“gbk”);
//ui->textEdit->setText( codec->toUnicode(array) );
文件對象關閉 close

6.1.2. 寫

file.open( QIODevice::writeOnly / Append)
file.write(內容)
file.close 關閉

6.2. QFileInfo

讀取文件信息
QFileInfo info(路徑)
qDebug() << “大小:” << info.size() << " 后綴名:" << info.suffix() << " 文件名稱:"<<info.fileName() << " 文件路徑:"<< info.filePath();
qDebug() << “創建日期:” << info.created().toString(“yyyy/MM/dd hh:mm:ss”);
qDebug() << “最后修改日期:”<<info.lastModified().toString(“yyyy-MM-dd hh:mm:ss”);

用法

#include "widget.h" #include "ui_widget.h" #include <QFileDialog> #include <QFile> #include <QTextCodec> #include <QFileInfo> #include <QDebug> #include <QDateTime> Widget::Widget(QWidget *parent) :QWidget(parent),ui(new Ui::Widget) {ui->setupUi(this);//點擊選取文件按鈕,彈出文件對話框connect(ui->pushButton,&QPushButton::clicked,[=](){QString path = QFileDialog::getOpenFileName(this,"打開文件","C:\\Users\\Desktop");//將路徑放入到lineEdit中ui->lineEdit->setText(path);//編碼格式類//QTextCodec * codec = QTextCodec::codecForName("gbk");//讀取內容 放入到 textEdit中// QFile默認支持的格式是 utf-8QFile file(path); //參數就是讀取文件的路徑//設置打開方式file.open(QIODevice::ReadOnly);//QByteArray array = file.readAll();QByteArray array;while( !file.atEnd()){array += file.readLine(); //按行讀}//將讀取到的數據 放入textEdit中ui->textEdit->setText(array);//ui->textEdit->setText( codec->toUnicode(array) );//對文件對象進行關閉file.close();//進行寫文件 // file.open(QIODevice::Append); //用追加方式進行寫 // file.write("啊啊啊啊啊"); // file.close();//QFileInfo 文件信息類QFileInfo info(path);qDebug() << "大小:" << info.size() << " 后綴名:" << info.suffix() << " 文件名稱:"<<info.fileName() << " 文件路徑:"<< info.filePath();qDebug() << "創建日期:" << info.created().toString("yyyy/MM/dd hh:mm:ss");qDebug() << "最后修改日期:"<<info.lastModified().toString("yyyy-MM-dd hh:mm:ss");});}Widget::~Widget() {delete ui; }

7. 總結

至此,Qt基礎入門結束,跟著視頻學也挺好的,=w=

總結

以上是生活随笔為你收集整理的Qt学习之Qt基础入门(下)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。