首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Qml中的QScrollArea : Flickable + QQuickPaintedItem

Qml中的QScrollArea : Flickable + QQuickPaintedItem
EN

Stack Overflow用户
提问于 2016-02-17 23:07:02
回答 1查看 1.3K关注 0票数 2

我试图在Qml的帮助下实现一些类似于QScrollArea的东西(在小工具的世界里)。我决定探索基于FlickableQQuickPaintedItem的项目(在我的例子中名为Drawer ):

代码语言:javascript
复制
Flickable {
  ...
  onContentXChanged(): {
  drawer.update()
  }

Drawer {
  id: drawer
  ...
}

Drawer的呈现目标被设置为FrameBufferObject。它的绘图函数如下所示:

代码语言:javascript
复制
void Drawer::paint(QPainter *painter)
{
   // Some function to compute rect which is needed to be redrawn
   QRect updateRect = computeUpdateRect();

   // How to shift contents of Frame buffer, e.g. to right, and draw only updateRect in this space?
}

想象一下我们如何在QScrollArea小部件中滚动,例如向左滚动:视区的所有条目都向右移动,左侧唯一的小矩形被重绘。我想用Flickable+QQuickPaintedItem来做同样的事情。但有些事情我不能理解:

如何在QQuickPaintedItem中操作帧缓冲区对象?也许在QML中有更正确的方式来实现QScrollArea

顺便问一下,在QQuickPaintedItem中是否默认启用双缓冲

对于Flickable的实现:提供更多关于任务的信息:我有一个非常大的“图景”。所以我不能将它整个加载到内存中,但我必须使用诸如viewport之类的东西来导航它。

EN

回答 1

Stack Overflow用户

发布于 2016-02-27 23:25:33

当您想要在较小的区域中封装较大的内容并在其周围导航时,可以使用滚动区或flickable。在你的情况下那是..。事实并非如此。你实际上并没有使用滚动区域,因为你的图像永远不会大于滚动区域的大小,你只是想要伪造它,这实际上很容易:

代码语言:javascript
复制
#include <QQuickPaintedItem>
#include <QImage>
#include <QPainter>

class PImage : public QQuickPaintedItem {
    Q_OBJECT
public:
    PImage(QQuickItem * p = 0) : QQuickPaintedItem(p), xpos(0), ypos(0) {}
    void paint(QPainter *painter) {
        if (!source.isNull()) painter->drawImage(QRect(0, 0, width(), height()), source, QRect(xpos, ypos, width(), height()));
        else painter->fillRect(QRect(0, 0, width(), height()), Qt::black);
    }
public slots:
    bool load(QString path) {
        source = QImage(path);
        return !source.isNull();
    }
    void moveBy(int x, int y) {
        int ox, oy;
        // don't go outside the image
        ox = x + xpos + width() <= source.width() ? x + xpos : source.width() - width();
        oy = y + ypos + height() <= source.height() ? y + ypos : source.height() - height();
        if (ox < 0) ox = 0;
        if (oy < 0) oy = 0;
        if (ox != xpos || oy != ypos) {
            xpos = ox;
            ypos = oy;
            update();
        }
    }
private:
    QImage source;
    int xpos, ypos;
};

在QML方面:

代码语言:javascript
复制
PImage {
    width: 300
    height: 300
    Component.onCompleted: load("d:/img.jpg") // a big image
    MouseArea {
        property int ix
        property int iy
        anchors.fill: parent
        onPressed: {
            ix = mouseX
            iy = mouseY
        }
        onPositionChanged: {
            parent.moveBy(ix - mouseX, iy - mouseY)
            ix = mouseX
            iy = mouseY
        }
    }
}

这只是一个快速的基本示例,还有很多需要改进和改进的地方。另请注意,如果源矩形的大小与目标矩形的大小不同,则可以轻松实现放大或缩小。你可以把它挂到flickable上,以获得“动态滚动”,而不是鼠标区域。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35460369

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档