该代码采用了 Control 1 模块的按钮
import QtQuick 2.14
import QtQuick.Controls 1.4
import QtQuick.Window 2.14
Window { //使用Window会出现闪烁的问题,改成ApplicationWindow就没问题了。
visible: true
width: 640
height: 480
title: qsTr("Hello World")
ExclusiveGroup {
id: naviGroup
}
Column {
Button {
id: page1
checkable: true
exclusiveGroup: naviGroup
onCheckedChanged: {
if(checked) {
console.log("1")
}
}
}
Button {
id: page2
checkable: true
exclusiveGroup: naviGroup
}
Button {
id: page3
checkable: true
exclusiveGroup: naviGroup
}
Button {
id: page4
checkable: true
exclusiveGroup: naviGroup
}
}
}
当我把根节点Window改成ApplicationWindow之后,闪烁的问题就不会出现了,我再次将ApplicationWindow改回Window之后,闪烁的问题就又出现了,所以为什么会出现闪烁的问题呢,为什么更换了窗口类型就不会出现闪烁呢?
【以下回答由 GPT 生成】
这个问题可能是由于窗口的双缓冲机制导致的。在Qt中,Window和ApplicationWindow是不同的窗口类型,它们有不同的渲染方式和双缓冲机制。在你的代码中,当你将根节点的Window改成ApplicationWindow时,闪烁的问题消失了,这是因为ApplicationWindow使用了双缓冲机制来渲染窗口,可以避免闪烁的情况发生。
双缓冲是一种常用的解决闪烁问题的方法。它通过在后台缓冲区进行绘制,然后将绘制结果一次性刷新到前台窗口上,避免了直接在前台窗口绘制的过程中出现闪烁的问题。在你的代码中,当你使用ApplicationWindow时,Qt会自动处理双缓冲,所以你不再看到控件闪烁的现象。
但是,当你将ApplicationWindow改回Window时,窗口不再使用双缓冲机制,默认情况下会直接在前台窗口进行绘制。这可能会导致闪烁的问题重新出现。为了解决这个问题,你可以尝试手动启用双缓冲机制。下面是一种可能的解决方案:
import QtQuick 2.14
import QtQuick.Controls 1.4
import QtQuick.Window 2.14
Window {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
flags: Qt.FramelessWindowHint | Qt.Window
Item {
width: parent.width
height: parent.height
DoubleBuffered {
id: buffer
width: parent.width
height: parent.height
Column {
Button {
id: page1
checkable: true
onCheckedChanged: {
if (checked) {
console.log("1")
}
}
}
Button {
id: page2
checkable: true
}
Button {
id: page3
checkable: true
}
Button {
id: page4
checkable: true
}
}
onPaint: {
// 在缓冲区绘制所有的子项
var painter = new QPainter()
painter.begin(buffer)
// 绘制背景色或背景图像
painter.fillRect(buffer.rect, Qt.transparent)
// 绘制子项
buffer.children.forEach(function(child) {
painter.render(child)
})
painter.end()
// 将缓冲区的绘制结果渲染到前台窗口
painter.begin(viewport)
painter.drawImage(viewport.rect, buffer.image, buffer.rect)
painter.end()
}
}
}
}
上述代码中使用了一个自定义的DoubleBuffered组件来手动启用双缓冲机制。该组件实际上是一个辅助项,它本身没有可见性,但它包含了一个和窗口一样大小的缓冲区(buffer),并且在onPaint事件中将所有的子项绘制到缓冲区中,最后再将缓冲区的绘制结果渲染到前台窗口中。
通过将你的控件放入DoubleBuffered组件中,并在onPaint事件中绘制到缓冲区中,可以避免直接在前台窗口中进行绘制,从而解决闪烁的问题。
希望这个解决方案对你有帮助。如果你还有其他问题,请随时向我提问。