在qml中拖动无框窗口“抖动”

Abd*_*oui 5 c++ qt qml qtquick2

我有一个无框架的ApplicationWindow,我想使用问题的答案使其可拖动。但是,正如某人在评论中说的那样,当我快速移动窗口时,它会摇晃很多

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

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;
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

如果我添加标签和一些元素,那就更糟了。

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

dur*_*der 8

我遇到了同样的问题,性能还可以,但是在Linux上,它在屏幕上跳跃并“摇晃”。我已经通过在C ++中编写一个帮助程序类(已将其公开为QML上下文属性)解决了该问题。这个解决方案对我有很大帮助。我有非常复杂的UI,它工作得很好,性能也很好。因此,让我们开始吧。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();
    }
};
Run Code Online (Sandbox Code Playgroud)

这是一个非常简单的类,只提供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();
}
Run Code Online (Sandbox Code Playgroud)

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
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

4)现在,您可以通过以下方式在任意窗口中使用此TitleBar了:

Window {
    id: root
    visible: true

    flags: Qt.FramelessWindowHint

    TitleBar {
        height: 20
        container: root
    }

    Text {
        text: qsTr("Hello World")
        anchors.centerIn: parent
    }
}
Run Code Online (Sandbox Code Playgroud)

当我实现标题栏的拖放时,主要问题是QML提供的连接线,此解决方案解决了该问题。如果我的解决方案可以为您提供帮助,请提供一些反馈。我真的很感兴趣:)