Qt學(xué)習(xí)教程之表格控件螞蟻線詳解
一、螞蟻線
摘自互動(dòng)百科:在圖像影像軟件中表示選區(qū)的動(dòng)態(tài)虛線,因?yàn)樘摼€閃爍的樣子像是一群螞蟻在跑,所以俗稱螞蟻線。在Poshop,After Effect等軟件中比較常見。
背景:用過(guò)excel的同學(xué)都知道,當(dāng)對(duì)單元格進(jìn)行復(fù)制時(shí),單元格周圍就會(huì)出現(xiàn)一個(gè)跑動(dòng)的矩形框,這個(gè)矩形框就被稱為螞蟻線。通過(guò)設(shè)置螞蟻線的線型和調(diào)整控件有效刷新次數(shù)我們可以得到不同的跑動(dòng)效果,這是一個(gè)非常有意思的現(xiàn)象。
本文將給大家詳細(xì)介紹關(guān)于Qt表格控件螞蟻線的相關(guān)內(nèi)容,分享出來(lái)供大家參考學(xué)習(xí),下面話不多說(shuō)了,來(lái)一起看看詳細(xì)的介紹吧。
二、效果展示
如下圖就是螞蟻線的效果截圖,單擊單元格時(shí),會(huì)繪制一個(gè)2個(gè)像素寬的外框;當(dāng)雙擊某個(gè)單元格時(shí),就會(huì)產(chǎn)生螞蟻線,螞蟻線的線型和跑動(dòng)速度都可以定制。文末會(huì)放出演示代碼下載鏈接。

三、實(shí)現(xiàn)
說(shuō)到Qt繪圖,肯定離不開paintEvent函數(shù),而且大多數(shù)的功能都可以通過(guò)重寫paintEvent函數(shù)來(lái)完成。凡是總有例外,當(dāng)控件本身就比較復(fù)雜,或者只需要重寫控件某一部分時(shí),就需要重寫一些其他東西來(lái)完成需求,比如表格螞蟻線繪制就屬于這個(gè)例外,當(dāng)我們重寫表格時(shí)就不能重寫paintEvent函數(shù),如果重寫這個(gè)函數(shù)那么表格的所有東西就需要我們自己去繪制,一個(gè)好的辦法就是重寫QStyledItemDelegate代理類,通過(guò)這個(gè)類我們可以定制表格控件的每一個(gè)項(xiàng)。下面我們就來(lái)仔細(xì)的分析下基于重寫代理類的實(shí)現(xiàn)細(xì)節(jié),理解下面4個(gè)實(shí)現(xiàn)維度后螞蟻線基本就完成了。
1、繪制區(qū)域
螞蟻線是針對(duì)表格項(xiàng)來(lái)進(jìn)行繪制的,因此首先想到的就是刷新表格某一項(xiàng)來(lái)進(jìn)行提高繪制效率,通過(guò)閱讀Qt源碼,找到QTableView::paintEvent函數(shù)中對(duì)表格項(xiàng)進(jìn)行了繪制,主要是通過(guò)調(diào)用QTableViewPrivate::drawCell函數(shù)來(lái)進(jìn)行每個(gè)單元格的繪制,該函數(shù)最后一行是通過(guò)QStyledItemDelegate類的paint方法來(lái)進(jìn)行繪制,與第三節(jié)第一段的說(shuō)明對(duì)應(yīng)起來(lái)。因此如果想進(jìn)行局部刷新看來(lái)困難比較大,因此最終決定每次刷新螞蟻線時(shí)對(duì)整個(gè)表格進(jìn)行刷新。
2、定時(shí)器
定時(shí)刷新,顧名思義就是我們需要一個(gè)定時(shí)器,定時(shí)刷新表格控件。首先想到的是我們自己維護(hù)一個(gè)QTimer,通過(guò)QTimer::timeout信號(hào)來(lái)刷新表格;除此之外QObject類已經(jīng)幫我們提供了一個(gè)timerEvent回調(diào)函數(shù),我們只需要通過(guò)startTime接口來(lái)啟動(dòng)一個(gè)定時(shí)器,timerEvent函數(shù)就會(huì)被定時(shí)調(diào)用,當(dāng)然了這個(gè)回調(diào)接口同時(shí)支持多個(gè)定時(shí)器,用timeID進(jìn)行區(qū)分每個(gè)定時(shí)器。
3、繪制策略
當(dāng)選擇一個(gè)單元格時(shí)(當(dāng)前單元格發(fā)現(xiàn)變化),繪制矩形框;繪制矩形框比較簡(jiǎn)單,這塊需要注意一個(gè)地方,就是當(dāng)繪制第一列的時(shí)候矩形框可能會(huì)跑出當(dāng)前項(xiàng),導(dǎo)致矩形框顯示不全。螞蟻線繪制時(shí)也存在這個(gè)問(wèn)題。
void GMPFileItemDelegate::DrawBorderRect( QPainter * painter, const QRect & rect, bool firstColumn ) const
{
painter->save();
QPen pen = painter->pen();
pen.setWidth(2);
pen.setColor(QColor(0, 132, 255));
painter->setPen(pen);
QRect tmpRect = rect;
if (firstColumn)
{
tmpRect.adjust(2, 1, -1, -1);
}
else
{
tmpRect.adjust(1, 1, -1, -1);
}
painter->drawRect(tmpRect);
painter->restore();
}
當(dāng)雙擊單元格時(shí)繪制螞蟻線,螞蟻線繪制是通過(guò)定時(shí)器進(jìn)行控制線框奔跑速度,這塊有一個(gè)需要注意的地方是只有當(dāng)定時(shí)器引起的繪制才會(huì)使起螞蟻線往前跑。
根據(jù)螞蟻線的偏移繪制開始的空白區(qū)域,螞蟻線是由7個(gè)像素的藍(lán)色和2個(gè)像素的空白循環(huán)組成,當(dāng)偏移10個(gè)像素時(shí),重新回到偏移1個(gè)像素。
if (startPoint != truthPoint && offset > 2)
{
QPolygon polygon;
for (int i = 4; i <= offset; ++i)//繪制前邊偏移的像素
{
if (polygon.size() >= 7)
{
break;
}
polygon.append(truthPoint - QPoint(i , 0));
}
painter->drawPoints(polygon);
}
4、界面刷新
qt自己又自己的界面刷新策略,平時(shí)使用比較多的也不外乎update(建議刷新)、repaint(強(qiáng)制刷新)兩個(gè)接口,但是這個(gè)兩個(gè)接口調(diào)用時(shí)也不是說(shuō)界面肯定會(huì)刷新,其實(shí)這兩個(gè)接口都是使用QWidgetBackingStoreTracker類的senUpdateRequest接口類來(lái)拋出的刷新界面事件,Qt窗口有一個(gè)dirtyWidget的概念,當(dāng)判定這個(gè)窗口為需要刷新的窗口時(shí)才會(huì)調(diào)用sendUpdateRequest接口進(jìn)行界面刷新,如下代碼,update和repaint區(qū)別在于調(diào)用了switch的不同分支。
void QWidgetBackingStore::sendUpdateRequest(QWidget *widget, UpdateTime updateTime)
{
if (!widget)
return;
switch (updateTime) {
case UpdateLater:
updateRequestSent = true;
QApplication::postEvent(widget, new QEvent(QEvent::UpdateRequest), Qt::LowEventPriority);
break;
case UpdateNow: {
QEvent event(QEvent::UpdateRequest);
QApplication::sendEvent(widget, &event);
break;
}
}
}
對(duì)于表格控件當(dāng)我們單純調(diào)用repaint或者update函數(shù)時(shí)是不能起到刷新界面的作用,因此我們需要調(diào)用其他能直接導(dǎo)致界面刷新的接口,目前我這塊想到了直接調(diào)用窗口自身style的polish方法,如果大家有其他好的刷新方式可以留言。
通過(guò)以上4個(gè)小點(diǎn)的說(shuō)明,螞蟻線的實(shí)現(xiàn)基本就完成了。需要完整源碼的去csdn下載吧
四、下載鏈接
總結(jié)
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問(wèn)大家可以留言交流,謝謝大家對(duì)腳本之家的支持。
- Qt圖形圖像開發(fā)之曲線圖模塊QCustomplot庫(kù)生成靜態(tài)、動(dòng)態(tài)曲線詳細(xì)教程圖解
- Qt圖形圖像開發(fā)之高性能曲線圖模塊QCustomplot庫(kù)詳細(xì)使用方法與實(shí)例(支持動(dòng)、靜曲線圖)
- Qt學(xué)習(xí)教程之對(duì)話框消失動(dòng)畫效果
- Qt 使用Poppler實(shí)現(xiàn)pdf閱讀器的示例代碼
- Qt實(shí)現(xiàn)保存、瀏覽、預(yù)覽、打印功能的示例代碼
- QT開發(fā)應(yīng)用程序的歡迎界面實(shí)例
- QT網(wǎng)絡(luò)編程Tcp下C/S架構(gòu)的即時(shí)通信實(shí)例
- 在QT5中實(shí)現(xiàn)求兩個(gè)輸入值的和并輸出(實(shí)例)
- QT網(wǎng)絡(luò)編程UDP下C/S架構(gòu)廣播通信(實(shí)例講解)
- 淺談Qt中使用CEF的幾個(gè)要點(diǎn)(Windows下)
- 深入理解Qt中各種消息框?qū)υ捒虻氖褂?/a>
- Qt實(shí)現(xiàn)FTP的上傳和下載的實(shí)例代碼
- Qt如何設(shè)置窗口屏幕居中顯示以及設(shè)置大小
- Qt圖形圖像開發(fā)之曲線圖表庫(kù)QChart編譯安裝詳細(xì)方法與使用實(shí)例
相關(guān)文章
C++ Boost命令行解析庫(kù)的應(yīng)用詳解
命令行解析庫(kù)是一種用于簡(jiǎn)化處理命令行參數(shù)的工具,它可以幫助開發(fā)者更方便地解析命令行參數(shù)并提供適當(dāng)?shù)膸椭畔?本文主要介紹了不同的命令行解析庫(kù)和它們?cè)贑++項(xiàng)目中的應(yīng)用,希望對(duì)大家有所幫助2023-11-11
C++實(shí)現(xiàn)LeetCode(95.獨(dú)一無(wú)二的二叉搜索樹之二)
這篇文章主要介紹了C++實(shí)現(xiàn)LeetCode(95.獨(dú)一無(wú)二的二叉搜索樹之二),本篇文章通過(guò)簡(jiǎn)要的案例,講解了該項(xiàng)技術(shù)的了解與使用,以下就是詳細(xì)內(nèi)容,需要的朋友可以參考下2021-07-07
c語(yǔ)言生成隨機(jī)數(shù)的方法(獲得一組不同的隨機(jī)數(shù))
c語(yǔ)言生成一組不同的隨機(jī)數(shù),大家參考使用吧2013-12-12
C語(yǔ)言每日練習(xí)之統(tǒng)計(jì)文本單詞數(shù)及高頻詞
本文文大家準(zhǔn)備了個(gè)C語(yǔ)言練習(xí)題:統(tǒng)計(jì)單詞數(shù)并找出頻率最高的單詞,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)C語(yǔ)言有一定幫助,感興趣的可以了解一下2022-05-05
Vscode配置C/C++環(huán)境使用minGW(保姆級(jí)配置過(guò)程)

