翻譯|使用教程|編輯:鮑佳佳|2021-04-16 11:05:06.817|閱讀 416 次
概述:本示例說明如何使用QPainter進行渲染以創建基于QWindow的最小應用程序。
# 界面/圖表報表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
相關鏈接:
Qt是一個跨平臺框架,通常用作圖形工具包,它不僅創建CLI應用程序中非常有用。而且它也可以在三種主要的臺式機操作系統以及移動操作系統(如Symbian,Nokia Belle,Meego Harmattan,MeeGo或BB10)以及嵌入式設備,Android(Necessitas)和iOS的端口上運行。現在我們為你提供了免費的試用版。
Qt組件推薦:
本示例說明如何使用QPainter進行渲染以創建基于QWindow的最小應用程序。
應用程序入口點
int main(int argc, char **argv) { QGuiApplication app(argc, argv); RasterWindow window; window.show(); return app.exec(); }
基于QWindow的應用程序的入口點是QGuiApplication類。它管理著GUI應用程序的控制流程和主要設置。我們傳遞命令行參數,這些參數可以用來拾取某些系統范圍的選項。
從那里,我們繼續創建我們的窗口實例,然后調用QWindow::show()函數來告訴窗口系統,現在應該讓這個窗口在屏幕上可見。
一旦完成,我們進入應用程序的事件循環,這樣應用程序就可以運行了。
RasterWindow聲明
#include <QtGui> class RasterWindow : public QWindow { Q_OBJECT public: explicit RasterWindow(QWindow *parent = 0); virtual void render(QPainter *painter); public slots: void renderLater(); void renderNow(); protected: bool event(QEvent *event) override; void resizeEvent(QResizeEvent *event) override; void exposeEvent(QExposeEvent *event) override; private: QBackingStore *m_backingStore; };
我們首先要加入<QtGui>頭。這意味著我們可以使用Qt GUI模塊中的所有類。如果喜歡的話,也可以單獨包含類。
RasterWindow類直接對QWindow進行子類化,并提供了一個構造函數,它允許窗口成為另一個QWindow的子窗口。無父類的QWindow在窗口系統中顯示為頂層窗口。
該類聲明了一個QBackingStore,我們用它來管理基于QPainter的圖形的窗口回緩沖區。
柵格窗口在其他一些例子中也被重用,并增加了一些輔助函數,比如renderLater()。
RasterWindow實施
RasterWindow::RasterWindow(QWindow *parent) : QWindow(parent) , m_backingStore(new QBackingStore(this)) { setGeometry(100, 100, 300, 200); }
在構造函數中,我們創建后備存儲,并將應管理的窗口實例傳遞給后備存儲。我們還設置了初始窗口的幾何形狀。
void RasterWindow::exposeEvent(QExposeEvent *) { if (isExposed()) renderNow(); }
在創建的窗口上調用QWindow::show()后不久,會調用虛擬函數QWindow::exposeEvent()來通知我們窗口在窗口系統中的曝光度發生了變化。該事件包含了暴露的子區域,但由于我們每次都會繪制整個窗口,所以我們并沒有使用這個函數。
函數QWindow::isExposed()將告訴我們窗口是否顯示。我們需要這個函數,因為當窗口在窗口系統中變得模糊時,exposeEvent也會被調用。如果窗口正在顯示,我們調用renderNow()來立即繪制窗口。我們希望立即繪制,這樣我們就可以給系統呈現一些視覺內容。
void RasterWindow::resizeEvent(QResizeEvent *resizeEvent) { m_backingStore->resize(resizeEvent->size()); }
保證在窗口顯示在屏幕上之前調用resize事件,并且在窗口在屏幕上調整窗口大小時也會調用該事件。我們使用它來調整后臺緩沖區的大小,并將渲染推遲到相應的/隨后的暴露事件。
void RasterWindow::renderNow() { if (!isExposed()) return; QRect rect(0, 0, width(), height()); m_backingStore->beginPaint(rect); QPaintDevice *device = m_backingStore->paintDevice(); QPainter painter(device); painter.fillRect(0, 0, width(), height(), QGradient::NightFade); render(&painter); painter.end(); m_backingStore->endPaint(); m_backingStore->flush(rect); }
renderNow函數設置了QWindow使用QPainter渲染其內容所需的內容。由于被遮擋的窗口是不可見的,所以如果該窗口在窗口系統中沒有暴露,我們就會中止。例如,當另一個窗口完全遮擋住這個窗口時,就會發生這種情況。
我們通過調用QBackingStore::beginPaint()來開始繪制我們想要繪制的區域。然后我們得到后方緩沖區的QPaintDevice,并創建一個QPainter來渲染到該繪畫設備。
為了使之前的渲染留下的痕跡無效,并以一個干凈的緩沖區開始,我們用白色填充整個緩沖區。然后我們調用虛擬的render()函數,對這個窗口進行實際的繪制。
繪制完成后,我們調用endPaint()來表示我們已經完成了渲染,并使用QBackingStore::flush()來呈現后面緩沖區中的內容。
void RasterWindow::render(QPainter *painter) { painter->drawText(QRectF(0, 0, width(), height()), Qt::AlignCenter, QStringLiteral("QWindow")); }
渲染函數包含了窗口的繪制代碼,在這個最小的例子中,我們只在中間繪制 "QWindow "這個字符串。在這個最小的例子中,我們只在中間繪制 "QWindow "這個字符串。
異步渲染
void RasterWindow::renderLater() { requestUpdate(); }
我們經歷了幾個需要立即重繪窗口的地方。有些情況下,這樣做并不可取,而是讓應用程序返回事件循環,并將重繪安排在以后進行。我們通過請求更新,使用QWindow::requestUpdate()來實現,當系統準備好重新繪制時,更新將被傳遞。
bool RasterWindow::event(QEvent *event) { if (event->type() == QEvent::UpdateRequest) { renderNow(); return true; } return QWindow::event(event); }
我們重新實現虛擬QObject::event()函數來處理更新事件。當事件發生時,我們調用renderNow()來立即渲染窗口。
====================================================
想要了解或購買Qt正版授權的朋友,歡迎
Qt技術交流群現已開通,QQ搜索群號“765444821”或者掃描下方二維碼即可加入
本站文章除注明轉載外,均為本站原創或翻譯。歡迎任何形式的轉載,但請務必注明出處、不得修改原文相關鏈接,如果存在內容上的異議請郵件反饋至chenjj@fc6vip.cn
文章轉載自: