翻譯|使用教程|編輯:龔雪|2023-11-07 11:07:26.007|閱讀 124 次
概述:本文將為大家介紹Qt Widget的模擬時鐘示例,歡迎下載最新版組件體驗~
# 界面/圖表報表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
相關(guān)鏈接:
Qt 是目前最先進(jìn)、最完整的跨平臺C++開發(fā)工具。它不僅完全實現(xiàn)了一次編寫,所有平臺無差別運行,更提供了幾乎所有開發(fā)過程中需要用到的工具。如今,Qt已被運用于超過70個行業(yè)、數(shù)千家企業(yè),支持?jǐn)?shù)百萬設(shè)備及應(yīng)用。
Qt技術(shù)交流群:166830288 歡迎一起進(jìn)群討論
模擬時鐘示例展示了如何繪制自定義小部件的內(nèi)容,這個示例還演示了如何使用QPainter的轉(zhuǎn)換和縮放特性來更輕松地繪制自定義小部件。
AnalogClock類提供了一個帶有時針和分針的時鐘小部件,每隔幾秒鐘自動更新一次,我們繼承了QWidget并重新實現(xiàn)了標(biāo)準(zhǔn)的paintEvent()函數(shù)來繪制鐘面:
class AnalogClock : public QWidget { Q_OBJECT public: AnalogClock(QWidget *parent = nullptr); protected: void paintEvent(QPaintEvent *event) override; };
AnalogClock::AnalogClock(QWidget *parent) : QWidget(parent) { QTimer *timer = new QTimer(this); connect(timer, &QTimer::timeout, this, QOverload<>::of(&AnalogClock::update)); timer->start(1000); setWindowTitle(tr("Analog Clock")); resize(200, 200); }
在構(gòu)造小部件時,我們設(shè)置一個1秒計時器來跟蹤當(dāng)前時間,并將其連接到標(biāo)準(zhǔn)update()插槽,以便在計時器發(fā)出timeout()信號時更新時鐘面。
最后我們調(diào)整小部件的大小,使其顯示在一個合理的大小。
void AnalogClock::paintEvent(QPaintEvent *) { static const QPoint hourHand[3] = { QPoint(7, 8), QPoint(-7, 8), QPoint(0, -40) }; static const QPoint minuteHand[3] = { QPoint(7, 8), QPoint(-7, 8), QPoint(0, -70) }; QColor hourColor(127, 0, 127); QColor minuteColor(0, 127, 127, 191); int side = qMin(width(), height());
每當(dāng)需要更新小部件的內(nèi)容時,就調(diào)用paintEvent()函數(shù)。這在小部件首次顯示時發(fā)生,在它被覆蓋然后暴露時發(fā)生,但在小部件的update()槽被調(diào)用時也會執(zhí)行。由于我們將計時器的timeout()信號連接到這個槽,因此它將至少每五秒被調(diào)用一次。
在我們設(shè)置painter和繪制時鐘之前,首先定義兩個QPoints和兩個QColors列表,它們將用于時針和分針。分針的顏色alpha值為191,這意味著它75%是不透明的。
我們還確定了小部件最短邊的長度,以便可以將鐘面放入小部件中,在開始繪圖之前確定當(dāng)前時間也很有用。
QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing); painter.translate(width() / 2, height() / 2); painter.scale(side / 200.0, side / 200.0);
自定義小部件的內(nèi)容是用QPainter繪制的,Painters可以用來在任何QPaintDevice上繪畫,但它們通常與小部件一起使用,因此我們將小部件實例傳遞給painter的構(gòu)造函數(shù)。
我們用QPainter::Antialiasing調(diào)用QPainter::setRenderHint()來打開反鋸齒,這使得繪制對角線更加平滑。
平移將原點移動到小部件的中心,縮放操作確保以下繪圖操作被縮放來適應(yīng)小部件。我們使用一個比例因子,讓使用-100到100之間的x和y坐標(biāo),這確保了它們位于小部件最短邊的長度范圍內(nèi)。
為了使代碼更簡單,我們將繪制一個固定大小的鐘面,并對其進(jìn)行定位和縮放,使其位于小部件的中心。
painter負(fù)責(zé)在繪制事件期間進(jìn)行的所有轉(zhuǎn)換,并確保所有內(nèi)容都被正確繪制,讓繪圖器處理轉(zhuǎn)換通常比僅僅為了繪制自定義小部件的內(nèi)容而執(zhí)行手動計算更容易。
我們先畫時針,使用一個公式,將坐標(biāo)系逆時針旋轉(zhuǎn)數(shù)度,由當(dāng)前的小時和分鐘決定,這意味著手將顯示順時針旋轉(zhuǎn)所需的量。
painter.setPen(Qt::NoPen); painter.setBrush(hourColor);
我們將pen設(shè)置為Qt::NoPen,因為不想要任何輪廓,并且使用適合顯示小時數(shù)的顏色固體畫筆,筆刷在填充多邊形和其他幾何形狀時使用。
painter.save(); painter.rotate(30.0 * ((time.hour() + time.minute() / 60.0))); painter.drawConvexPolygon(hourHand, 3); painter.restore();
我們保存并恢復(fù)旋轉(zhuǎn)前后的變換矩陣,因為想要放置分針,而不必考慮之前的任何旋轉(zhuǎn)。
painter.setPen(hourColor); for (int i = 0; i < 12; ++i) { painter.drawLine(88, 0, 96, 0); painter.rotate(30.0); }
我們在時鐘的邊緣畫上標(biāo)記,代表每小時。繪制每個標(biāo)記,然后旋轉(zhuǎn)坐標(biāo)系統(tǒng),以便painter準(zhǔn)備好下一個。
painter.setPen(Qt::NoPen); painter.setBrush(minuteColor); painter.save(); painter.rotate(6.0 * (time.minute() + time.second() / 60.0)); painter.drawConvexPolygon(minuteHand, 3); painter.restore();
分針的旋轉(zhuǎn)方式與時針相似。
painter.setPen(minuteColor); for (int j = 0; j < 60; ++j) { if ((j % 5) != 0) painter.drawLine(92, 0, 96, 0); painter.rotate(6.0); } }
同樣我們在時鐘的邊緣畫上標(biāo)記,但這次是用來表示分鐘。跳過5的倍數(shù),以避免在小時標(biāo)記上畫分鐘標(biāo)記。
本站文章除注明轉(zhuǎn)載外,均為本站原創(chuàng)或翻譯。歡迎任何形式的轉(zhuǎn)載,但請務(wù)必注明出處、不得修改原文相關(guān)鏈接,如果存在內(nèi)容上的異議請郵件反饋至chenjj@fc6vip.cn
文章轉(zhuǎn)載自:慧都網(wǎng)