我想基于两个QComboBox的选定文本启用或禁用QDialogButtonBox或最好仅启用QDialog中的“确定”按钮。
我的示例如下。当前不起作用,启用或禁用QDialogButtonBox时,两个ComboBox彼此独立工作。
import sys
from PyQt5.QtCore import QSignalMapper, pyqtSlot
from PyQt5.QtWidgets import (QGroupBox, QFormLayout, QLabel, QComboBox,
QApplication, QDialog, QDialogButtonBox,
QVBoxLayout)
class SheetColumns(QDialog):
def __init__(self, column_header):
super().__init__()
self.setMinimumWidth(300)
self.setWindowTitle("Input Column Names")
self.column_headers = column_header
self.column_headers.insert(0, ' ')
self.setWhatsThis('Please match columns in your data sheet names'
' with the right side labels')
col_names = ["Student Name:", "Student ID:", "Cohort:", "Gender:",
"College:", "Department:", "Major:", "Minor", "Email:",
"Adviser", "Adviser Email"]
self.form_group_box = QGroupBox("Specify Column Names")
self.layout = QFormLayout()
for col_name in col_names:
combo = QComboBox()
combo.addItems(self.column_headers)
self.layout.addRow(QLabel(col_name), combo)
self.form_group_box.setLayout(self.layout)
self.button_box = QDialogButtonBox(
QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
self.button_box.setEnabled(False)
self.layout.itemAt(0, 1).widget().currentTextChanged.connect(
self.check_validity)
self.layout.itemAt(1, 1).widget().currentTextChanged.connect(
self.check_validity)
self.button_box.accepted.connect(self.accept)
self.button_box.rejected.connect(self.reject)
main_layout = QVBoxLayout()
main_layout.addWidget(self.form_group_box)
main_layout.addWidget(self.button_box)
self.setLayout(main_layout)
def check_validity(self, text):
print(text)
if text == ' ':
self.button_box.setEnabled(False)
else:
self.button_box.setEnabled(True)
if __name__ == '__main__':
app = QApplication(sys.argv)
dialog = SheetColumns(['name student', 'id', 'cohort', 'test 1'])
sys.exit(dialog.exec_())
我希望当两个ComboBox中的currentText不是''时启用QDialogButtonBox,而当它们都为''时禁用QDialogButtonBox。
我尝试使用
QSignalMapper
。但是,我无法使其正常运行。
class SheetColumns(QDialog):
def __init__(self, column_header):
super().__init__()
self.setMinimumWidth(300)
self.setWindowTitle("Input Column Names")
self.column_headers = column_header
self.column_headers.insert(0, ' ')
self.setWhatsThis('Please match columns in your data sheet names'
' with the right side labels')
col_names = ["Student Name:", "Student ID:", "Cohort:", "Gender:",
"College:", "Department:", "Major:", "Minor", "Email:",
"Adviser", "Adviser Email"]
self.form_group_box = QGroupBox("Specify Column Names")
self.layout = QFormLayout()
for col_name in col_names:
combo = QComboBox()
combo.addItems(self.column_headers)
self.layout.addRow(QLabel(col_name), combo)
self.form_group_box.setLayout(self.layout)
self.button_box = QDialogButtonBox(
QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
self.button_box.setEnabled(False)
self.mapper = QSignalMapper(self)
comb_bx1 = self.layout.itemAt(0, 1).widget()
comb_bx2 = self.layout.itemAt(1, 1).widget()
comb_bx1.currentTextChanged.connect(self.mapper.map)
comb_bx2.currentTextChanged.connect(self.mapper.map)
self.mapper.setMapping(comb_bx1, comb_bx1.currentText())
self.mapper.setMapping(comb_bx2, comb_bx2.currentText())
self.mapper.mapped.connect(self.check_validity)
self.button_box.accepted.connect(self.accept)
self.button_box.rejected.connect(self.reject)
main_layout = QVBoxLayout()
main_layout.addWidget(self.form_group_box)
main_layout.addWidget(self.button_box)
self.setLayout(main_layout)
def check_validity(self, text):
print(text)
if text == ' ':
self.button_box.setEnabled(False)
else:
self.button_box.setEnabled(True)
有人可以告诉我我做错了什么吗,还是有更好的办法?
提前致谢
最佳答案
使用QSignalMapper可以满足您的需求,在这种情况下,您只需要遍历QComboBox并确认它们没有适当的选项,并根据该选项启用按钮,如下所示:
class SheetColumns(QDialog):
def __init__(self, column_header, parent=None):
super().__init__(parent)
self.setMinimumWidth(300)
self.setWindowTitle("Input Column Names")
self.column_headers = column_header
self.setWhatsThis(
"Please match columns in your data sheet names"
" with the right side labels"
)
col_names = [
"Student Name:",
"Student ID:",
"Cohort:",
"Gender:",
"College:",
"Department:",
"Major:",
"Minor",
"Email:",
"Adviser",
"Adviser Email",
]
self.combos = []
flay = QFormLayout()
for i, col_name in enumerate(col_names):
combo = QComboBox()
combo.addItems([""] + self.column_headers)
flay.addRow(col_name, combo)
if i in (0, 1):
combo.currentIndexChanged.connect(self.check_validity)
self.combos.append(combo)
self.form_group_box = QGroupBox("Specify Column Names")
self.form_group_box.setLayout(flay)
self.button_box = QDialogButtonBox(
QDialogButtonBox.Ok | QDialogButtonBox.Cancel
)
self.button_box.accepted.connect(self.accept)
self.button_box.rejected.connect(self.reject)
main_layout = QVBoxLayout(self)
main_layout.addWidget(self.form_group_box)
main_layout.addWidget(self.button_box)
@pyqtSlot()
def check_validity(self):
is_enabled = True
for combo in self.combos:
if not combo.currentText():
is_enabled = False
break
button = self.button_box.button(QDialogButtonBox.Ok)
button.setEnabled(is_enabled)
@TheKewlStore在他的答案中指出了一些错误:QObjects的所有权不是由Python处理,而是由C ++部分处理。 python中一个QObject的所有权具有一个创建它的类,如果它是一个属性(在OP的示例中不满足),或者具有另一个QObject,它是在创建它或使用setParent时设置的父对象() 方法。对于QWidget,当您将其添加到布局中时,它会将其管理的小部件设置为父级。在您的情况下,QComboBoxes的所有权是QGroupBox,因此GC没有问题。
关于python - 基于多个QComboBox的文本启用或禁用QDialogButtonBox,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/59181970/