当我按下 QSpinbox 中的箭头时,如何防止双 valueChanged 事件?
Posted
技术标签:
【中文标题】当我按下 QSpinbox 中的箭头时,如何防止双 valueChanged 事件?【英文标题】:How do I prevent double valueChanged events when I press the arrows in a QSpinbox? 【发布时间】:2017-01-10 12:33:47 【问题描述】:可能是 Qt 错误,也可能是我的应用程序中的错误,我希望有人可以帮助我诊断此问题。
我正在构建一个带有使用 qtdesigner 和 pyuic5 构建的界面的 PyQt5 应用程序。
我必须在我的窗口中QSpinBox
小部件,我连接到这样的两种方法:
self.img1IndexBox.valueChanged.connect(self.changeImage1)
self.img2IndexBox.valueChanged.connect(self.changeImage2)
在应用程序中似乎一切正常,除了一件事:如果我将鼠标滚动到微调框上,我可以让它增加值。如果我用文本更改值,一切正常。如果我在微调框上使用键盘箭头,它工作正常。但是,如果我单击旋转框中的向上或向下箭头,我会得到两个 changeValue
事件,一个双倍增量。就像我点击了两次一样。事实上,它甚至可以从动画中看出它正在为按下创建一个事件,并在按钮返回时创建另一个事件。
这可能只是一个库错误,或者是什么导致我的程序出现这种情况?我该如何调试呢?
【问题讨论】:
【参考方案1】:您可以通过将 spinbox enable 设置为 false 来防止这种双重情况。 然后在处理大数据后使其为true。
点击向上/向下箭头时 on_value 已更改 ui->spinbox->setEnabled(false);
然后在函数 on_valuechanged 结束之前设置为 true。 ui->spinbox->setEnabled(true);
【讨论】:
【参考方案2】:显然问题是事件触发了一个很长的例程,这延迟了“按钮释放”事件,并且有足够的时间让系统认为用户实际上正在按住按钮,产生更多事件......但是我仍然有兴趣了解什么是一个很好的步行。是否有一种不错的 pyqt-onic 方法来为该方法启动线程?
http://www.qtcentre.org/archive/index.php/t-43078.html
【讨论】:
大多数解决方案都涉及创建一个完整的 QObject 来处理这个问题,但我正在更新 matplotlib FigureCanvasQTAgg 中的绘图,这需要很长时间。因此,最好弄清楚如何创建一个可以以更自然的方式做到这一点的小部件。 所以画布实际上有同步draw()
和异步 draw_idle()
方法,使用这可能是要走的路。很抱歉发布这样的问题和答案,我希望将这些信息放在一起可能对某人有用。【参考方案3】:
而不是使用valueChanged.connect
使用editingFinished.connect
它将确保仅在提供值后调用该函数。
PyQt
import sys
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QDoubleSpinBox, QApplication, QMainWindow, QWidget, QVBoxLayout, QLabel, QSpinBox
class MainWindow(QWidget):
def __init__(self):
super().__init__()
self.initUI()
# def valueChanged(self, value):
# print(value)
def valueChanged(self):
print(f"Value changed new value is : self.spinBox.value()")
def initUI(self):
self.setGeometry(0, 0, 200, 100)
self.layout = QVBoxLayout()
self.spinBox = QSpinBox()
self.spinBox.setAlignment(Qt.AlignCenter)
self.spinBox.setRange(0, 1000)
# self.spinBox.valueChanged.connect(self.valueChanged)
self.spinBox.editingFinished.connect(self.valueChanged)
self.layout.addWidget(self.spinBox)
self.setLayout(self.layout)
if __name__ == "__main__":
app = QApplication(sys.argv)
main = MainWindow()
main.show()
sys.exit(app.exec())
PySide
import sys
from PySide6.QtWidgets import QDoubleSpinBox, QApplication, QMainWindow, QWidget, QVBoxLayout, QLabel, QSpinBox
from PySide6.QtGui import Qt
class MainWindow(QWidget):
def __init__(self):
super().__init__()
self.initUI()
# def valueChanged(self, value):
# print(value)
def valueChanged(self):
print(f"Value changed new value is : self.spinBox.value()")
def initUI(self):
self.setGeometry(0, 0, 200, 100)
self.layout = QVBoxLayout()
self.spinBox = QSpinBox()
self.spinBox.setAlignment(Qt.AlignCenter)
self.spinBox.setRange(0, 1000)
# self.spinBox.valueChanged.connect(self.valueChanged)
self.spinBox.editingFinished.connect(self.valueChanged)
self.layout.addWidget(self.spinBox)
self.setLayout(self.layout)
if __name__ == "__main__":
app = QApplication(sys.argv)
main = MainWindow()
main.show()
sys.exit(app.exec())
【讨论】:
以上是关于当我按下 QSpinbox 中的箭头时,如何防止双 valueChanged 事件?的主要内容,如果未能解决你的问题,请参考以下文章
当我按下表格中的按钮时如何设置输入值?这里我使用 laravel 5.8