Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Qt 调整大小期间不重新绘制窗口_Qt_Qml_Qt Quick_Qtquick2 - Fatal编程技术网

Qt 调整大小期间不重新绘制窗口

Qt 调整大小期间不重新绘制窗口,qt,qml,qt-quick,qtquick2,Qt,Qml,Qt Quick,Qtquick2,我的QML应用程序(Qt5.4)基于窗口项。用户可以调整应用程序的大小。调整应用程序大小时,将分别调整应用程序内容的大小(使用onWidthChanged和onHeightChanged) 这一切都很好 但是为了避免闪烁,我不想在应用程序调整大小时更新应用程序的内容。QML中是否有可能检测用户何时实际调整窗口大小(在窗口边界上按住鼠标按钮),并且在调整完毕(释放鼠标按钮)之前不重新计算内容?编辑:Kuba Ober建议的方法非常简单和可靠,我仍然会在这里留下我的答案,因为我发现它有点有趣(并且C

我的QML应用程序(Qt5.4)基于
窗口
项。用户可以调整应用程序的大小。调整应用程序大小时,将分别调整应用程序内容的大小(使用
onWidthChanged
onHeightChanged

这一切都很好


但是为了避免闪烁,我不想在应用程序调整大小时更新应用程序的内容。QML中是否有可能检测用户何时实际调整窗口大小(在窗口边界上按住鼠标按钮),并且在调整完毕(释放鼠标按钮)之前不重新计算内容?

编辑:Kuba Ober建议的方法非常简单和可靠,我仍然会在这里留下我的答案,因为我发现它有点有趣(并且C++自定义组件方法可以修改以过滤窗口事件,如建议)。
请原谅,我写了一篇快速而难看的文章,看看是否可能,它只涵盖了你问题的第二部分(不更新内容)。 我的解决方案会阻止项目的重新绘制,但也会在请求对其进行更新时将其隐藏(这对您来说可能不是问题)

在阅读了文档,尤其是这个短语之后

如果用户已在项目上设置QQuickItem::ItemHasContents标志,则该函数将作为QQuickItem::update()的结果调用

< P>我创建了一个C++类,在一个abqQuQuiType:

上设置/取消这个标志
#ifndef ITEMUPDATEBLOCKER_H
#define ITEMUPDATEBLOCKER_H

#include <QObject>
#include <QQuickItem>


class ItemUpdateBlocker : public QObject
{
    Q_OBJECT
    Q_PROPERTY(QQuickItem* target READ target WRITE setTarget NOTIFY targetChanged)
    QQuickItem* m_target;

public:
    explicit ItemUpdateBlocker(QObject *parent = 0) : QObject(parent), m_target(nullptr) {  }
    QQuickItem* target() const { return m_target; }

signals:
    void targetChanged();

private:
    static void blockUpdate(QQuickItem* target)
    {
        if (target)
            target->setFlag(QQuickItem::ItemHasContents, false);
    }

    static void unblockUpdate(QQuickItem* target)
    {
        if (target)
        {
            target->setFlag(QQuickItem::ItemHasContents, true);
            target->update();
        }
    }


public slots:
    void setTarget(QQuickItem* target)
    {
        if (m_target == target)
            return;
        unblockUpdate(m_target);
        blockUpdate(target);
        m_target = target;
        emit targetChanged();
    }
};

#endif // ITEMUPDATEBLOCKER_H
当然,您可以向阻止程序添加一个
active
属性来简化它的使用(比使用null
target
来禁用它更漂亮),但我将把它作为练习

也许你可以在
窗口的宽度或高度发生变化时启动计时器,我还没有找到一种直接的方法来确定窗口的大小

但是为了避免闪烁,我不想在应用程序调整大小时更新应用程序的内容

我也有同样的意图,然后发现在我的例子中,当窗口不经常重新绘制时,它已经足以避免闪烁和高CPU负载。这可以通过计时器实现:

import QtQuick 2.12
import QtQuick.Controls 2.12

Window {
    id: root

    onWidthChanged: {
        redrawTimer.running ? redrawTimer.restart() : redrawTimer.start()
    }

    onHeightChanged: {
        redrawTimer.running ? redrawTimer.restart() : redrawTimer.start()
    }

    Timer {
        id: redrawTimer
        interval: 100
        onTriggered: {
            content.width  = ...
            content.height = ...
        }
    }

    // Actual content of your window, here assumed to be in a custom QML type.
    WindowContent {
        id: content
    }
}
上面的代码创建了一个窗口,该窗口仅在过去100毫秒内未收到调整大小事件时才重新绘制。这样,在调整大小结束和重新绘制之间,以及在调整大小期间暂停鼠标移动和重新绘制之间,会有一个很小但几乎不明显的延迟


这种方法尤其适用于具有快速、低质量和慢速、高质量重绘方式的元素,例如与SVG源一起使用的Qt QML
Image
类型。在这种情况下,基于光栅图形的缩放速度很快,可以在使用QML布局或锚定机制调整窗口大小期间完成,从而创建“预览”。通过设置重新绘制SVG的速度很慢,只有在如上所示的计时器触发时才会进行。

过滤相关事件,直到松开鼠标按钮。具体来说,在按住鼠标按钮的同时“吃掉”调整大小事件,然后在释放鼠标后合成最终的调整大小事件。您可以在连接到显示QML界面的窗口/小部件对象的事件筛选器中完成这一切。我尝试了这一方法,但问题是在调整窗口大小时,您没有获得鼠标按下或释放事件,并且
QGuiApplication::mouseButtons
返回没有按下任何按钮。
import QtQuick 2.4
import QtQuick.Controls 1.3
import QtQuick.Window 2.2
import com.mycompany.qmlcomponents 1.0

ApplicationWindow {

    width: 640
    height: 480
    visible: true

    Rectangle {
        color: "red"
        id: root
        anchors.fill: parent

        Text {
            text: blocker.target ? "Blocked" : "Not Blocked"
        }

        Rectangle {
            color: "white"
            anchors.centerIn: parent
            width: parent.width/2
            height: parent.height/2

            ItemUpdateBlocker {
                id: blocker;
            }

            MouseArea {
                anchors.fill: parent
                onClicked: blocker.target = blocker.target ? null : parent
            }
        }
    }
}
import QtQuick 2.12
import QtQuick.Controls 2.12

Window {
    id: root

    onWidthChanged: {
        redrawTimer.running ? redrawTimer.restart() : redrawTimer.start()
    }

    onHeightChanged: {
        redrawTimer.running ? redrawTimer.restart() : redrawTimer.start()
    }

    Timer {
        id: redrawTimer
        interval: 100
        onTriggered: {
            content.width  = ...
            content.height = ...
        }
    }

    // Actual content of your window, here assumed to be in a custom QML type.
    WindowContent {
        id: content
    }
}