拖动无框窗口“抖动";在 qml

2022-01-19 00:00:00 qt qtquick2 qml c++

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

I have a frameless ApplicationWindow and I wanted to make it draggable using the answer of this question. However, as someone said in a comment, when I move the window fastly, it jiggles a lot.

我一直在尝试改进它,但没有成功.

I've been trying to improve it but without success.

ApplicationWindow {
    visible: true
    width: 640
    height: 480
    title: qsTr("WIP")
    id: mainWindow
    flags: Qt.SubWindow | Qt.Tool | Qt.FramelessWindowHint | Qt.WindowSystemMenuHint
    header: ToolBar{

        MouseArea{
            anchors.fill: parent
            onDoubleClicked: mainWindow.visibility!="2"?mainWindow.showNormal():mainWindow.showMaximized()
            id: maMainWindow
            property variant clickPos: "0,0"

            onPressed: {
                clickPos  = Qt.point(mouse.x,mouse.y)
            }

            onPositionChanged: {
                    var delta = Qt.point(mouse.x-clickPos.x, mouse.y-clickPos.y)
                    mainWindow.x += delta.x;
                    mainWindow.y += delta.y;
            }
        }
    }
}

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

If I add tabs and some elements it makes it worse.

C++ 能否以某种方式提高其性能?

Can C++ improve its performance somehow?

推荐答案

我也遇到了同样的问题,性能还可以,但是在linux上却是满屏跳,抖动".我已经通过在 C++ 中编写一个帮助程序类来解决它,我已经将它公开为 QML 上下文属性.这个解决方案对我帮助很大.我有非常复杂的用户界面,它工作得非常好,性能非常好.所以让我们开始吧.1) 你需要一个类似这样的辅助类:

I had the same problem, the performance was ok, but on linux it was jumping all over the screen and "jiggling". I have solved it by writing a helper class in C++ which I have exposed as QML context property. This solution helped me a lot. I have very complex UI and it works perfectly fine, with very good performance. So lets get started. 1) You will need a helper class something like this:

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 引擎,我已经通过以下方式完成了:

It is a really simple class which just provides you cursor position from C++ side, it is strange, but when you do the same in QML you get problems(at least on linux). 2) Expose it as context property to QML engine, I have done it in next way:

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,如下所示:

3) Ok, now we are ready to go with QML part. I have a Qt Quick component that implements a TitleBar for frameless window, like this:

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 了:

4) Now you are ready to use this TitleBar in arbitrary window in next way:

Window {
    id: root
    visible: true

    flags: Qt.FramelessWindowHint

    TitleBar {
        height: 20
        container: root
    }

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

当我为标题栏实现拖放时,主要问题在于 QML 提供的绳索,此解决方案解决了该问题.如果我的解决方案对您有帮助,请提供一些反馈.我真的很感兴趣:)

When I was implementing drag&drop for title bar the main problem is in cords that QML provides, this solution fixes that issue. Please provide some feedback if my solution will help you. I'm really interested:)

相关文章