在 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上下文属性。这个解决方案对我帮助很大。我有一个非常复杂的UI,它工作得非常好,性能非常好。让我们开始吧。1)您将需要一个像这样的helper类:
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快速组件,实现了无框窗口的标题栏,像这样:
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
}
}
}
现在你可以在任意窗口中使用标题栏了
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元素的相对位置。我怀疑这是因为内部那些对象是在"绝对屏幕空间"中绘制的,所以当你移动窗口时,这会导致每个元素的实际绝对位置发生变化,即使它们相对于窗口保持在相同的位置,也会导致这种行为。不理想……这不仅引入了不希望的视觉行为,而且还引入了许多额外的计算,这些计算似乎是不必要的开销。
请注意,这些只是我模糊的怀疑,我还没有详细调查这件事,希望有人能提供一个快速简单的方法来处理这个问题。现在我忽略了这个问题,希望它不会太烦人,考虑到我专注于软件,这不是关于窗口的位置和几何形状的连续变化;)顺便说一句,虽然我第一次在QML中看到这个,但最近几年我在其他"现代gui"框架中也注意到它。这是可以理解的,因为这些框架为了快速原型而转向执行较慢的语言,并结合"流畅的"异步非阻塞渲染。- 如何在Qt窗口小部件中使用QStringView(或QStringRef)
- 问:如何使用C++中的按钮从窗口打开窗口
- SDL 窗口不会弹出
- 在createdialog创建的窗口中捕获用于编辑控件的OnMouseMove消息
- 如何在cpp文件之间切换窗口?在Qt中
- QuadTree只在窗口的右上角绘制
- VS Code "command":"make"与终端窗口中的命令行"make"不同
- 如何在C++中找到active directory中禁用和锁定的窗口帐户
- 处理闪烁窗口事件
- 如何通过按下第三个窗口中的按钮,将QString从一个窗口获取到另一个窗口
- C++win32 API创建多个类似视口的窗口
- SFML RenderWindow打开窗口需要很长时间
- 如何将不同的可执行文件合并到一个窗口框架中进行编码?像浏览器一样
- 获取 SFML 窗口的 HWND 和高可用性?
- 如何获取 GLFW 窗口 ID?
- GLEW/GLUT:调用init并创建一个窗口后,取消初始化并重新初始化?
- 用于窗口的 HID 终端
- SFML 文本未绘制在窗口上
- 如何为窗口截屏
- 在 qml 中拖动无框窗口"jiggles"