簡體   English   中英

在qml中拖動無框窗口“jiggles”

[英]Dragging frameless window “jiggles” in qml

我有一個無框架的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;
            }
        }
    }
}

如果我添加標簽和一些元素會使情況變得更糟。

C ++可以以某種方式改善其性能嗎?

我遇到了同樣的問題,性能還可以,但是在linux上,它在屏幕上跳躍並“搖搖晃晃”。 我已經通過在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提供的線索,此解決方案修復了該問題。 如果我的解決方案能為您提供幫助,請提供反饋。 我真的很感興趣:)

我認為你無法做任何事情,這只是使用綁定來構建GUI並且綁定評估與渲染不同步的副作用。 結果,當您移動窗口或調整窗口大小時,一切都像彈性一樣搖晃,直到值“趕上”。 這是一個QML的東西,在小部件中你沒有得到那種行為,因為UI不是圍繞綁定構建的。 基本上,每個綁定鏈的評估都有延遲,並且由於GUI是繪制它捕獲並顯示綁定鏈傳播的延遲,鏈中的第一個對象已經在它們的新位置,而那些進一步向后可以通過傳播的幾個步驟落后。 當然,你的窗戶是否有框架與這個問題完全無關。

克服這一點需要控制綁定如何處理信號,我認為目前沒有這樣的事情。 基本上,訣竅是以某種方式迫使繪圖等待,直到鏈中的每個綁定被評估,並在啟動另一系列評估之前介入。

當然,你擁有的元素越多,每次變化所需的時間越長,所有這些變化都會更加明顯。 它還取決於你的系統有多快 - 因為這決定了評估綁定鏈的延遲,例如我的系統很快,你的示例代碼不會產生抖動。 然而,雖然在調整大小期間發生這種情況是可以理解的,但是當你只是簡單地移動窗口時,它就會引發一個問題。 畢竟,這不應該真正改變窗口中UI元素的相對位置。 我懷疑這是因為內部的那些對象是在“絕對屏幕空間”中繪制的,所以當您移動窗口時,這會導致每個元素的實際絕對位置發生變化,即使它們保持在相對於窗口的相同位置,從而導致這種行為。 不理想......不僅會引入不受歡迎的視覺行為,還會產生許多額外的評估,這些評估似乎是不必要的開銷。

請注意,這些只是我的模糊懷疑,我沒有詳細調查此事,希望有人可以提供一種快速簡便的方法來處理這個問題。 現在我忽略了這個問題,希望它不會太煩人,因為我專注於軟件而不是窗口的位置和幾何形狀的連續變化;)BTW即使我第一次在QML中看到這個,在過去的幾年里,我也注意到了其他“現代gui”框架。 這是可以理解的,因為為了快速原型設計,這種框架轉向性能較低的語言,並結合“流暢的”異步非阻塞渲染。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM