拖动无框窗口" jiggles"在qml中

时间:2016-08-22 21:15:39

标签: c++ qt qml qtquick2

我有一个无框架的ApplicationWindow,我希望使用this问题的答案使其可拖动。然而,正如有人在评论中所说,当我快速移动窗口时,它会摇晃很多

我一直试图改善它,但没有成功。

Java Build Path

如果我添加标签和一些元素会使情况变得更糟。

C ++能否以某种方式改善其性能?

2 个答案:

答案 0 :(得分:5)

我遇到了同样的问题,性能还可以,但是在Linux上,它在整个屏幕上都跳了起来,并且#34; jiggling"。我已经通过在C ++中编写一个帮助器类来解决它,我将它作为QML上下文属性公开。这个解决方案给了我很多帮助。我有非常复杂的用户界面,它工作得很好,性能非常好。 让我们开始吧。 1)你需要一个这样的辅助类:

class CursorPosProvider : public QObject
{
    Q_OBJECT
public:
    explicit CursorPosProvider(QObject *parent = nullptr) : QObject(parent)
    {
    }
    virtual ~CursorPosProvider() = default;

    Q_INVOKABLE QPointF cursorPos()
    {
        return QCursor::pos();
    }
};

这是一个非常简单的类,只是从C ++端提供光标位置,这很奇怪,但是当你在QML中做同样的事情时,你会遇到问题(至少在linux上)。 2)将它作为上下文属性公开给QML引擎,我已经完成了下一步:

int main(int argc, char *argv[])
{
    QGuiApplication app(argc, argv);

    QQuickView view;

    CursorPosProvider mousePosProvider;

    view.rootContext()->setContextProperty("mousePosition", &mousePosProvider);

    view.setSource(QUrl(QStringLiteral("qrc:/main.qml")));

    return app.exec();
}

3)好的,现在我们准备好了QML部分。 我有一个Qt Quick组件,它为无框窗口实现了TitleBar,如下所示:

Rectangle {
    id: root
    width: parent.width
    color: "#0099d6" // just random one

    property QtObject container

    // extra properties, maybe some signals

    MouseArea {
        id: titleBarMouseRegion
        property var clickPos
        anchors.fill: parent
        onPressed: {
            clickPos = { x: mouse.x, y: mouse.y }
        }
        onPositionChanged: {
            container.x = mousePosition.cursorPos().x - clickPos.x
            container.y = mousePosition.cursorPos().y - clickPos.y
        }
    }
}

4)现在您已准备好在下一个方向的任意窗口中使用此TitleBar:

Window {
    id: root
    visible: true

    flags: Qt.FramelessWindowHint

    TitleBar {
        height: 20
        container: root
    }

    Text {
        text: qsTr("Hello World")
        anchors.centerIn: parent
    }
}

当我为标题栏实现拖放时,主要问题在于QML提供的线索,此解决方案解决了这个问题。 如果我的解决方案能为您提供帮助,请提供反馈。我真的很感兴趣:)。

答案 1 :(得分:1)

我认为你无法做任何事情,只是使用绑定来构建GUI并且绑定评估与渲染不同步的副作用。结果,当您移动窗口或调整窗口大小时,一切都像弹性一样摇晃,直到值“赶上”。这是一个QML的东西,在小部件中你没有得到那种行为,因为UI不是围绕绑定构建的。基本上,每个绑定链的评估都有延迟,并且由于GUI是绘制它捕获并显示绑定链传播的延迟,链中的第一个对象已经在它们的新位置,而那些进一步向后可以通过传播的几个步骤落后。当然,你的窗户是否有框架与这个问题完全无关。

克服这个问题需要控制绑定如何处理信号,我认为目前没有这样的事情。基本上,诀窍是以某种方式迫使绘图等待,直到评估链中的每个绑定,并在启动另一系列评估之前介入。

自然地,你拥有的元素越多,每次改变所需的时间越长,所有这些元素都会级联,从而使效果更加明显。它还取决于系统的速度 - 因为这决定了评估绑定链的延迟,例如我的系统很快,你的示例代码不会产生抖动。然而,虽然在调整大小期间发生这种情况是可以理解的,但是当你只是简单地移动窗口时,它就会引发一个问题。毕竟,这不应该真正改变窗口中UI元素的相对位置。我怀疑这是因为内部的那些对象是在“绝对屏幕空间”中绘制的,所以当您移动窗口时,这会导致每个元素的实际绝对位置发生变化,即使它们保持在相对于窗口的相同位置,从而导致这种行为。不理想......不仅会引入不受欢迎的视觉行为,还会引入许多额外的评估,这些评估似乎是不必要的开销。

请注意,这些只是我的模糊怀疑,我没有详细调查此事,希望有人可以提供一种快速简便的方法来解决这个问题。现在我忽略了这个问题,希望它不会太烦人,因为我专注于软件而不是窗口的位置和几何形状的连续变化;)BTW即使我第一次在QML中看到这个,在过去的几年里,我也注意到了其他“现代gui”框架。这是可以理解的,因为为了快速原型设计,这种框架转向性能较低的语言,并结合“流畅的”异步非阻塞渲染。