您好,登錄后才能下訂單哦!
摘自互動百科:在圖像影像軟件中表示選區的動態虛線,因為虛線閃爍的樣子像是一群螞蟻在跑,所以俗稱螞蟻線。在Poshop,After Effect等軟件中比較常見。
背景:用過excel的同學都知道,當對單元格進行復制時,單元格周圍就會出現一個跑動的矩形框,這個矩形框就被稱為螞蟻線。通過設置螞蟻線的線型和調整控件有效刷新次數我們可以得到不同的跑動效果,這是一個非常有意思的現象。
本文將給大家詳細介紹關于Qt表格控件螞蟻線的相關內容,分享出來供大家參考學習,下面話不多說了,來一起看看詳細的介紹吧。
如下圖就是螞蟻線的效果截圖,單擊單元格時,會繪制一個2個像素寬的外框;當雙擊某個單元格時,就會產生螞蟻線,螞蟻線的線型和跑動速度都可以定制。文末會放出演示代碼下載鏈接。
說到Qt繪圖,肯定離不開paintEvent函數,而且大多數的功能都可以通過重寫paintEvent函數來完成。凡是總有例外,當控件本身就比較復雜,或者只需要重寫控件某一部分時,就需要重寫一些其他東西來完成需求,比如表格螞蟻線繪制就屬于這個例外,當我們重寫表格時就不能重寫paintEvent函數,如果重寫這個函數那么表格的所有東西就需要我們自己去繪制,一個好的辦法就是重寫QStyledItemDelegate代理類,通過這個類我們可以定制表格控件的每一個項。下面我們就來仔細的分析下基于重寫代理類的實現細節,理解下面4個實現維度后螞蟻線基本就完成了。
螞蟻線是針對表格項來進行繪制的,因此首先想到的就是刷新表格某一項來進行提高繪制效率,通過閱讀Qt源碼,找到QTableView::paintEvent函數中對表格項進行了繪制,主要是通過調用QTableViewPrivate::drawCell函數來進行每個單元格的繪制,該函數最后一行是通過QStyledItemDelegate類的paint方法來進行繪制,與第三節第一段的說明對應起來。因此如果想進行局部刷新看來困難比較大,因此最終決定每次刷新螞蟻線時對整個表格進行刷新。
定時刷新,顧名思義就是我們需要一個定時器,定時刷新表格控件。首先想到的是我們自己維護一個QTimer,通過QTimer::timeout信號來刷新表格;除此之外QObject類已經幫我們提供了一個timerEvent回調函數,我們只需要通過startTime接口來啟動一個定時器,timerEvent函數就會被定時調用,當然了這個回調接口同時支持多個定時器,用timeID進行區分每個定時器。
當選擇一個單元格時(當前單元格發現變化),繪制矩形框;繪制矩形框比較簡單,這塊需要注意一個地方,就是當繪制第一列的時候矩形框可能會跑出當前項,導致矩形框顯示不全。螞蟻線繪制時也存在這個問題。
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(); }
當雙擊單元格時繪制螞蟻線,螞蟻線繪制是通過定時器進行控制線框奔跑速度,這塊有一個需要注意的地方是只有當定時器引起的繪制才會使起螞蟻線往前跑。
根據螞蟻線的偏移繪制開始的空白區域,螞蟻線是由7個像素的藍色和2個像素的空白循環組成,當偏移10個像素時,重新回到偏移1個像素。
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); }
qt自己又自己的界面刷新策略,平時使用比較多的也不外乎update(建議刷新)、repaint(強制刷新)兩個接口,但是這個兩個接口調用時也不是說界面肯定會刷新,其實這兩個接口都是使用QWidgetBackingStoreTracker類的senUpdateRequest接口類來拋出的刷新界面事件,Qt窗口有一個dirtyWidget的概念,當判定這個窗口為需要刷新的窗口時才會調用sendUpdateRequest接口進行界面刷新,如下代碼,update和repaint區別在于調用了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; } } }
對于表格控件當我們單純調用repaint或者update函數時是不能起到刷新界面的作用,因此我們需要調用其他能直接導致界面刷新的接口,目前我這塊想到了直接調用窗口自身style的polish方法,如果大家有其他好的刷新方式可以留言。
通過以上4個小點的說明,螞蟻線的實現基本就完成了。需要完整源碼的去csdn下載吧
Qt螞蟻線-表格
總結
以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對億速云的支持。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。