如何使用 QDoubleSpinBoxes 更改 QDoubleSpinBoxes 中的值?
How to change values in QDoubleSpinBoxes using with QDoubleSpinBoxes?
下面是我的例子和我的代码尝试:
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(QtWidgets.QMainWindow):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(469, 348)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.gridLayout_3 = QtWidgets.QGridLayout(self.centralwidget)
self.gridLayout_3.setObjectName("gridLayout_3")
self.frame = QtWidgets.QFrame(self.centralwidget)
self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.frame.setFrameShadow(QtWidgets.QFrame.Raised)
self.frame.setObjectName("frame")
self.gridLayout_2 = QtWidgets.QGridLayout(self.frame)
self.gridLayout_2.setObjectName("gridLayout_2")
self.total_spin = QtWidgets.QDoubleSpinBox(self.frame)
self.total_spin.setObjectName("total_spin")
self.gridLayout_2.addWidget(self.total_spin, 0, 1, 1, 1)
self.totalLabel = QtWidgets.QLabel(self.frame)
self.totalLabel.setObjectName("totalLabel")
self.gridLayout_2.addWidget(self.totalLabel, 0, 0, 1, 1)
self.gridLayout = QtWidgets.QGridLayout()
self.gridLayout.setObjectName("gridLayout")
self.SpinBox_two = QtWidgets.QDoubleSpinBox(self.frame)
self.SpinBox_two.setObjectName("SpinBox_two")
self.gridLayout.addWidget(self.SpinBox_two, 1, 0, 1, 1)
self.two_amount = QtWidgets.QDoubleSpinBox(self.frame)
self.two_amount.setObjectName("two_amount")
self.gridLayout.addWidget(self.two_amount, 1, 1, 1, 1)
self.five_amount = QtWidgets.QDoubleSpinBox(self.frame)
self.five_amount.setObjectName("five_amount")
self.gridLayout.addWidget(self.five_amount, 4, 1, 1, 1)
self.SpinBox_one = QtWidgets.QDoubleSpinBox(self.frame)
self.SpinBox_one.setObjectName("SpinBox_one")
self.gridLayout.addWidget(self.SpinBox_one, 0, 0, 1, 1)
self.three_amount = QtWidgets.QDoubleSpinBox(self.frame)
self.three_amount.setObjectName("three_amount")
self.gridLayout.addWidget(self.three_amount, 2, 1, 1, 1)
self.one_amount = QtWidgets.QDoubleSpinBox(self.frame)
self.one_amount.setObjectName("one_amount")
self.gridLayout.addWidget(self.one_amount, 0, 1, 1, 1)
self.SpinBox_three = QtWidgets.QDoubleSpinBox(self.frame)
self.SpinBox_three.setObjectName("SpinBox_three")
self.gridLayout.addWidget(self.SpinBox_three, 2, 0, 1, 1)
self.SpinBox_four = QtWidgets.QDoubleSpinBox(self.frame)
self.SpinBox_four.setObjectName("SpinBox_four")
self.gridLayout.addWidget(self.SpinBox_four, 3, 0, 1, 1)
self.four_amount = QtWidgets.QDoubleSpinBox(self.frame)
self.four_amount.setObjectName("four_amount")
self.gridLayout.addWidget(self.four_amount, 3, 1, 1, 1)
self.SpinBox_five = QtWidgets.QDoubleSpinBox(self.frame)
self.SpinBox_five.setObjectName("SpinBox_five")
self.gridLayout.addWidget(self.SpinBox_five, 4, 0, 1, 1)
self.gridLayout_2.addLayout(self.gridLayout, 1, 0, 1, 2)
self.gridLayout_3.addWidget(self.frame, 0, 0, 1, 1)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 469, 21))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
####
self.one_amount.setReadOnly(True)
self.two_amount.setReadOnly(True)
self.three_amount.setReadOnly(True)
self.four_amount.setReadOnly(True)
self.five_amount.setReadOnly(True)
self.total_spin.setMaximum(99999999.99)
self.one_amount.setMaximum(99999999.99)
self.two_amount.setMaximum(99999999.99)
self.three_amount.setMaximum(99999999.99)
self.four_amount.setMaximum(99999999.99)
self.five_amount.setMaximum(99999999.99)
self.SpinBox_one.setMaximum(100.00)
self.boxes = [self.SpinBox_one, self.SpinBox_two, self.SpinBox_three, self.SpinBox_four, self.SpinBox_five]
self.SpinBox_one.valueChanged.connect(self.limit)
self.SpinBox_two.valueChanged.connect(self.limit)
self.SpinBox_three.valueChanged.connect(self.limit)
self.SpinBox_four.valueChanged.connect(self.limit)
####
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.totalLabel.setText(_translate("MainWindow", "total"))
###
def limit(self, value):
i = self.boxes.index(self.sender())
total = value + sum(box.value() for box in self.boxes[:i])
for box in self.boxes[i + 1:]:
box.blockSignals(True) # Avoid extra calls to limit()
box.setMaximum(100 - total)
box.blockSignals(False)
total += box.value()
if self.SpinBox_one.valueChanged:
self.one_amount.setValue(self.total_spin.value() / 100 * self.SpinBox_one.value())
if self.SpinBox_two.valueChanged:
self.two_amount.setValue(self.total_spin.value() / 100 * self.SpinBox_two.value())
if self.SpinBox_three.valueChanged:
self.three_amount.setValue(self.total_spin.value() / 100 * self.SpinBox_three.value())
if self.SpinBox_four.valueChanged:
self.four_amount.setValue(self.total_spin.value() / 100 * self.SpinBox_four.value())
if self.SpinBox_five.valueChanged:
self.five_amount.setValue(self.total_spin.value() / 100 * self.SpinBox_five.value())
###
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
它有 total_spin 手动设置值的框,5 个名为 self.SpinBox_one, self.SpinBox_two, self.SpinBox_three, self.SpinBox_four, self.SpinBox_five
的 QDoubleSpinBoxes 将使用以下代码手动设置值,限制为 100%:
def limit(self, value):
i = self.boxes.index(self.sender())
total = value + sum(box.value() for box in self.boxes[:i])
for box in self.boxes[i + 1:]:
box.blockSignals(True) # Avoid extra calls to limit()
box.setMaximum(100 - total)
box.blockSignals(False)
total += box.value()
和另外5个名为self.one_amount, self.SpinBox_three, self.SpinBox_four, self.SpinBox_five
的QDoubleSpinBoxes将在self.SpinBox_one, self.SpinBox_two, self.SpinBox_three, self.SpinBox_four, self.SpinBox_five
值更改时自动设置值。例如:如果 self.SpinBox_one 值更改,将执行 self.total_spin.value() / 100 * self.SpinBox_one.value()
并将计算值设置为 self.one_amount
。而剩下的也在发生link这个。
但是最后一个(self.SpinBox_five
)不起作用。如果 self.SpinBox_five.valueChanged
值改变了它不计算也不设置值。 self.five_amount.setValue(self.total_spin.value() / 100 * self.SpinBox_five.value())
。如何解决上述问题和第二个问题是:它不应该覆盖百分比值:例如:如果我将 5 self.SpinBox_one, self.SpinBox_two, self.SpinBox_three, self.SpinBox_four, self.SpinBox_five
值(百分比)设置为 50, 20, 10, 10, 10
并且如果我将第一个值从 50 更改到 60,它会将最后一个框 10 更改为 0。在这种情况下,如果 100% 打包,则在每个 QDoubleSpinBoxes 中都不应更改。如果值(百分比)为 50, 20, 10, 10
并且最后一个为空。在这种情况下,上述 self.SpinBox_one, self.SpinBox_two, self.SpinBox_three, self.SpinBox_four
之一可以添加剩余的 10%。之后应该打包。如何做到这一点。
如果我没理解错的话,您希望所有旋转框在总值为 100 时锁定,并且不允许旋转框覆盖其下方的值.在这种情况下,limit
函数将更易于实现,但因此当总值达到 100 时,需要先减少其中一个旋转框,然后才能增加其中任何一个。
此外,这些语句 - if self.SpinBox_one.valueChanged:
- 不会比较旋转框是否发出信号(使用 QObject.sender()
来做到这一点)。 valueChanged
属性 指向该对象的 pyqtBoundSignal 并且将始终评估为 True 只是因为它存在。现在更好的结构是将旋转框放在字典中。
self.boxes = {self.SpinBox_one: self.one_amount,
self.SpinBox_two: self.two_amount,
self.SpinBox_three: self.three_amount,
self.SpinBox_four: self.four_amount,
self.SpinBox_five: self.five_amount}
对于每个框,将其最大值设置为其当前值 + 100 中的剩余金额。并且可以分配与发件人对应的旋转框的值,无需任何比较。
def limit(self, value):
remainder = 100 - sum(box.value() for box in self.boxes)
for box in self.boxes:
box.setMaximum(box.value() + remainder)
self.boxes[self.sender()].setValue(self.total_spin.value() / 100 * value)
如评论中所述,只是提醒连接 SpinBox_five。
self.SpinBox_five.valueChanged.connect(self.limit)
下面是我的例子和我的代码尝试:
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(QtWidgets.QMainWindow):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(469, 348)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.gridLayout_3 = QtWidgets.QGridLayout(self.centralwidget)
self.gridLayout_3.setObjectName("gridLayout_3")
self.frame = QtWidgets.QFrame(self.centralwidget)
self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.frame.setFrameShadow(QtWidgets.QFrame.Raised)
self.frame.setObjectName("frame")
self.gridLayout_2 = QtWidgets.QGridLayout(self.frame)
self.gridLayout_2.setObjectName("gridLayout_2")
self.total_spin = QtWidgets.QDoubleSpinBox(self.frame)
self.total_spin.setObjectName("total_spin")
self.gridLayout_2.addWidget(self.total_spin, 0, 1, 1, 1)
self.totalLabel = QtWidgets.QLabel(self.frame)
self.totalLabel.setObjectName("totalLabel")
self.gridLayout_2.addWidget(self.totalLabel, 0, 0, 1, 1)
self.gridLayout = QtWidgets.QGridLayout()
self.gridLayout.setObjectName("gridLayout")
self.SpinBox_two = QtWidgets.QDoubleSpinBox(self.frame)
self.SpinBox_two.setObjectName("SpinBox_two")
self.gridLayout.addWidget(self.SpinBox_two, 1, 0, 1, 1)
self.two_amount = QtWidgets.QDoubleSpinBox(self.frame)
self.two_amount.setObjectName("two_amount")
self.gridLayout.addWidget(self.two_amount, 1, 1, 1, 1)
self.five_amount = QtWidgets.QDoubleSpinBox(self.frame)
self.five_amount.setObjectName("five_amount")
self.gridLayout.addWidget(self.five_amount, 4, 1, 1, 1)
self.SpinBox_one = QtWidgets.QDoubleSpinBox(self.frame)
self.SpinBox_one.setObjectName("SpinBox_one")
self.gridLayout.addWidget(self.SpinBox_one, 0, 0, 1, 1)
self.three_amount = QtWidgets.QDoubleSpinBox(self.frame)
self.three_amount.setObjectName("three_amount")
self.gridLayout.addWidget(self.three_amount, 2, 1, 1, 1)
self.one_amount = QtWidgets.QDoubleSpinBox(self.frame)
self.one_amount.setObjectName("one_amount")
self.gridLayout.addWidget(self.one_amount, 0, 1, 1, 1)
self.SpinBox_three = QtWidgets.QDoubleSpinBox(self.frame)
self.SpinBox_three.setObjectName("SpinBox_three")
self.gridLayout.addWidget(self.SpinBox_three, 2, 0, 1, 1)
self.SpinBox_four = QtWidgets.QDoubleSpinBox(self.frame)
self.SpinBox_four.setObjectName("SpinBox_four")
self.gridLayout.addWidget(self.SpinBox_four, 3, 0, 1, 1)
self.four_amount = QtWidgets.QDoubleSpinBox(self.frame)
self.four_amount.setObjectName("four_amount")
self.gridLayout.addWidget(self.four_amount, 3, 1, 1, 1)
self.SpinBox_five = QtWidgets.QDoubleSpinBox(self.frame)
self.SpinBox_five.setObjectName("SpinBox_five")
self.gridLayout.addWidget(self.SpinBox_five, 4, 0, 1, 1)
self.gridLayout_2.addLayout(self.gridLayout, 1, 0, 1, 2)
self.gridLayout_3.addWidget(self.frame, 0, 0, 1, 1)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 469, 21))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
####
self.one_amount.setReadOnly(True)
self.two_amount.setReadOnly(True)
self.three_amount.setReadOnly(True)
self.four_amount.setReadOnly(True)
self.five_amount.setReadOnly(True)
self.total_spin.setMaximum(99999999.99)
self.one_amount.setMaximum(99999999.99)
self.two_amount.setMaximum(99999999.99)
self.three_amount.setMaximum(99999999.99)
self.four_amount.setMaximum(99999999.99)
self.five_amount.setMaximum(99999999.99)
self.SpinBox_one.setMaximum(100.00)
self.boxes = [self.SpinBox_one, self.SpinBox_two, self.SpinBox_three, self.SpinBox_four, self.SpinBox_five]
self.SpinBox_one.valueChanged.connect(self.limit)
self.SpinBox_two.valueChanged.connect(self.limit)
self.SpinBox_three.valueChanged.connect(self.limit)
self.SpinBox_four.valueChanged.connect(self.limit)
####
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.totalLabel.setText(_translate("MainWindow", "total"))
###
def limit(self, value):
i = self.boxes.index(self.sender())
total = value + sum(box.value() for box in self.boxes[:i])
for box in self.boxes[i + 1:]:
box.blockSignals(True) # Avoid extra calls to limit()
box.setMaximum(100 - total)
box.blockSignals(False)
total += box.value()
if self.SpinBox_one.valueChanged:
self.one_amount.setValue(self.total_spin.value() / 100 * self.SpinBox_one.value())
if self.SpinBox_two.valueChanged:
self.two_amount.setValue(self.total_spin.value() / 100 * self.SpinBox_two.value())
if self.SpinBox_three.valueChanged:
self.three_amount.setValue(self.total_spin.value() / 100 * self.SpinBox_three.value())
if self.SpinBox_four.valueChanged:
self.four_amount.setValue(self.total_spin.value() / 100 * self.SpinBox_four.value())
if self.SpinBox_five.valueChanged:
self.five_amount.setValue(self.total_spin.value() / 100 * self.SpinBox_five.value())
###
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
它有 total_spin 手动设置值的框,5 个名为 self.SpinBox_one, self.SpinBox_two, self.SpinBox_three, self.SpinBox_four, self.SpinBox_five
的 QDoubleSpinBoxes 将使用以下代码手动设置值,限制为 100%:
def limit(self, value):
i = self.boxes.index(self.sender())
total = value + sum(box.value() for box in self.boxes[:i])
for box in self.boxes[i + 1:]:
box.blockSignals(True) # Avoid extra calls to limit()
box.setMaximum(100 - total)
box.blockSignals(False)
total += box.value()
和另外5个名为self.one_amount, self.SpinBox_three, self.SpinBox_four, self.SpinBox_five
的QDoubleSpinBoxes将在self.SpinBox_one, self.SpinBox_two, self.SpinBox_three, self.SpinBox_four, self.SpinBox_five
值更改时自动设置值。例如:如果 self.SpinBox_one 值更改,将执行 self.total_spin.value() / 100 * self.SpinBox_one.value()
并将计算值设置为 self.one_amount
。而剩下的也在发生link这个。
但是最后一个(self.SpinBox_five
)不起作用。如果 self.SpinBox_five.valueChanged
值改变了它不计算也不设置值。 self.five_amount.setValue(self.total_spin.value() / 100 * self.SpinBox_five.value())
。如何解决上述问题和第二个问题是:它不应该覆盖百分比值:例如:如果我将 5 self.SpinBox_one, self.SpinBox_two, self.SpinBox_three, self.SpinBox_four, self.SpinBox_five
值(百分比)设置为 50, 20, 10, 10, 10
并且如果我将第一个值从 50 更改到 60,它会将最后一个框 10 更改为 0。在这种情况下,如果 100% 打包,则在每个 QDoubleSpinBoxes 中都不应更改。如果值(百分比)为 50, 20, 10, 10
并且最后一个为空。在这种情况下,上述 self.SpinBox_one, self.SpinBox_two, self.SpinBox_three, self.SpinBox_four
之一可以添加剩余的 10%。之后应该打包。如何做到这一点。
如果我没理解错的话,您希望所有旋转框在总值为 100 时锁定,并且不允许旋转框覆盖其下方的值.在这种情况下,limit
函数将更易于实现,但因此当总值达到 100 时,需要先减少其中一个旋转框,然后才能增加其中任何一个。
此外,这些语句 - if self.SpinBox_one.valueChanged:
- 不会比较旋转框是否发出信号(使用 QObject.sender()
来做到这一点)。 valueChanged
属性 指向该对象的 pyqtBoundSignal 并且将始终评估为 True 只是因为它存在。现在更好的结构是将旋转框放在字典中。
self.boxes = {self.SpinBox_one: self.one_amount,
self.SpinBox_two: self.two_amount,
self.SpinBox_three: self.three_amount,
self.SpinBox_four: self.four_amount,
self.SpinBox_five: self.five_amount}
对于每个框,将其最大值设置为其当前值 + 100 中的剩余金额。并且可以分配与发件人对应的旋转框的值,无需任何比较。
def limit(self, value):
remainder = 100 - sum(box.value() for box in self.boxes)
for box in self.boxes:
box.setMaximum(box.value() + remainder)
self.boxes[self.sender()].setValue(self.total_spin.value() / 100 * value)
如评论中所述,只是提醒连接 SpinBox_five。
self.SpinBox_five.valueChanged.connect(self.limit)