彩票走势图

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

翻译|使用教程|编辑:鲍佳佳|2021-04-16 11:05:06.817|阅读 339 次

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

# 慧都年终大促·界面/图表报表/文档/IDE等千款热门软控件火热促销中 >>

相关链接:

Qt是一个跨平台框架,通常用作图形工具包,它不仅创建CLI应用程序中非常有用。而且它也可以在三种主要的台式机操作系统以及移动操作系统(如Symbian,Nokia Belle,Meego Harmattan,MeeGo或BB10)以及嵌入式设备,Android(Necessitas)和iOS的端口上运行。现在我们为你提供了免费的试用版。

下载Qt6最新试用版

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_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@pclwef.cn

文章转载自:

为你推荐

  • 推荐视频
  • 推荐活动
  • 推荐产品
  • 推荐文章
  • 慧都慧问
扫码咨询


添加微信 立即咨询

电话咨询

客服热线
023-68661681

TOP