C++跨平台开发框架Qt示例:栅格窗口示例

本示例说明如何使用QPainter进行渲染以创建基于QWindow的最小应用程序。

Qt组件推荐:

  • QtitanRibbon| 下载试用: 遵循Microsoft Ribbon UI Paradigm for Qt技术的Ribbon UI组件,致力于为Windows、Linux和Mac OS X提供功能完整的Ribbon组件。
  • QtitanChart | 下载试用 :是一个C ++库,代表一组控件,这些控件使您可以快速地为应用程序提供漂亮而丰富的图表。并且支持所有主要的桌面。
  • QtitanNavigation | 下载试用 :模拟Microsoft Dynamics CRM-2016/Office 365导航界面和一组控件改善Qt.C ++应用程序用户体验的QtitanNavigation组件。

本示例说明如何使用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_OBJECTpublic:    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或者扫描下方二维码即可加入

C++跨平台开发框架Qt示例:栅格窗口示例

标签:

来源:慧都

声明:本站部分文章及图片转载于互联网,内容版权归原作者所有,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2021年3月12日
下一篇 2021年3月12日

相关推荐

发表回复

登录后才能评论