我有一个QWizard,它读取CSV文件的列标题并使用户选择他们想要的每一列。在此向导的第二页中,我将组合框添加到for循环中,该循环遍历CSV的列名。所有组合框均为必填字段。但是,另一个限制是,在用户可以按“下一步”之前,必须至少选择其中一个来选择3或更高(在我的MWE中为c1或c2)。
除了self.NextButton.setEnabled(False)之外,我还根据此示例和此问题尝试使用isComplete和completeChanged,但由于是PyQt的初学者并且不太擅长C ++,所以我没有能够了解很多现有文档。目前,isComplete似乎还可以,但是向导未在注册它。
谁能教我如何实现我想要的目标(粗体文字)?
from PyQt5 import QtGui, QtWidgets, QtCore
import csv
class ChooseFile(QtWidgets.QWizardPage):
    def __init__(self, parent=None):
        super(ChooseFile, self).__init__(parent)
        body = QtWidgets.QVBoxLayout()
        self.filePathShow = QtWidgets.QLineEdit(self)
        self.filePathShow.setReadOnly(True)                      # not editable
        self.registerField("filePathShow\*, self.filePathShow)   # mandatory
        body.addWidget(self.filePathShow)
        browseButton = QtWidgets.QPushButton('Browse...', self)
        browseButton.clicked.connect(self.browseDialog)
        browseBox = QtWidgets.QHBoxLayout()
        browseBox.addWidget(browseButton)
        body.addLayout(browseBox)
        self.setLayout(body)
    def browseDialog(self):
        filePath, _ = QtWidgets.QFileDialog.getOpenFileName(self, 'Open CSV', '/home', '(\*csv)')
        if filePath:   # only changes if valid file, stays the same if user presses cancel
            self.setField("filePathShow", filePath)
class ChooseColumns(QtWidgets.QWizardPage):
    def __init__(self, parent=None):
        super(ChooseColumns, self).__init__(parent)
        self.box = QtWidgets.QGroupBox()
        body = QtWidgets.QVBoxLayout()
        body.addWidget(self.box)   # these are where the choices (comboboxes) go
        self.setLayout(body)
    def initializePage(self):
        filePath2 = self.field("filePathShow")
        with open(str(filePath2), 'r') as f:
            reader = csv.reader(f)
            self.columns = next(reader)            
            # make a combobox for each column
            grid = QtWidgets.QGridLayout()
            self.comboBoxes = [None] * len(self.columns)
            for i, col in enumerate(self.columns):
                grid.addWidget(QtWidgets.QLabel(col), i, 0)   # printscolumn name
                self.comboBoxes[i] = QtWidgets.QComboBox()
                self.comboBoxes[i].addItem("")         # default value since is mandatory field
                self.comboBoxes[i].addItem("a")
                self.comboBoxes[i].addItem("b")
                self.comboBoxes[i].addItem("c1")
                self.comboBoxes[i].addItem("c2")
                grid.addWidget(self.comboBoxes[i], i, 1)
                self.registerField("column" + str(i) + "\*, self.comboBoxes[i]) # all mandatory
                self.comboBoxes[i].currentIndexChanged.connect(self.isComplete)
                #self.connect(self.comboBoxes[i], QtCore.SIGNAL(currentIndexChanged()), 
                #            self, QtCore.SIGNAL(completeChanged()))
                self.comboBoxes[i].currentIndexChanged.connect(self.completeChanged)   # DOESN'T WORK
            self.box.setLayout(grid)
    def isComplete(self, other):   # WORKS
        self.selections = [None] * len(self.columns)
        for i in range(len(self.selections)):   # first fill the list
            self.selections[i] = self.comboBoxes[i].currentIndex()
        #print(self.selections)
        for item in self.selections:   # then evaluate the values
            if i >= 3:
                return True
        return False
class Manager(QtWidgets.QWizard):
    def __init__(self, parent=None):
        super(Manager, self).__init__(parent)
        self.resize(500, 300)
        self.addPage(ChooseFile(self))
        self.addPage(ChooseColumns(self))
if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)
    w = Manager()
    w.show()
    sys.exit(app.exec_())
 
问题来源:stackoverflow
版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。
isComplete信号必须返回一个布尔值,该值指示它可以前进到下一页还是终止该过程。此方法不应直接调用,而应通过completeChanged信号调用。
这种情况很特殊,因为QComboBox的数量是可变的,所以如果用户返回到上一页并选择另一个.csv,则应该更改QComboBox的数量并进行注册将是一个问题,因此在这种情况下我不会这样做但是它是使用isComplete直接处理的。
最后,由于目标(我想)是获取选定的值,因此我将使用QWizard的属性存储该信息,并能够在为测试添加的最后一页上获取它。
import csv
from PyQt5 import QtGui, QtWidgets, QtCore
class ChooseFile(QtWidgets.QWizardPage):
    def __init__(self, parent=None):
        super(ChooseFile, self).__init__(parent)
        body = QtWidgets.QVBoxLayout(self)
        self.filePathShow = QtWidgets.QLineEdit(self)
        self.filePathShow.setReadOnly(True)  # not editable
        self.registerField("filePathShow\*, self.filePathShow)  # mandatory
        body.addWidget(self.filePathShow)
        browseButton = QtWidgets.QPushButton("Browse...", self)
        browseButton.clicked.connect(self.browseDialog)
        browseBox = QtWidgets.QHBoxLayout()
        browseBox.addWidget(browseButton)
        body.addLayout(browseBox)
    def browseDialog(self):
        filePath, _ = QtWidgets.QFileDialog.getOpenFileName(
            self, "Open CSV", "/home", "(\*csv)"
        )
        if filePath:
            self.setField("filePathShow", filePath)
class ChooseColumns(QtWidgets.QWizardPage):
    def __init__(self, parent=None):
        super(ChooseColumns, self).__init__(parent)
        self.comboboxes = []
        box = QtWidgets.QGroupBox()
        lay = QtWidgets.QVBoxLayout(self)
        lay.addWidget(box)
        self.flay = QtWidgets.QFormLayout()
        box.setLayout(self.flay)
    def initializePage(self):
        for combo in self.comboboxes:
            self.flay.removeRow(combo)
        self.comboboxes = []
        self.wizard().setProperty("indexes_selected", [])
        self.wizard().setProperty("options_selected", [])
        filePath2 = self.field("filePathShow")
        options = ("", "a", "b", "c1", "c2")
        with open(filePath2, "r") as f:
            reader = csv.reader(f)
            header = next(reader)
            for i, text in enumerate(header):
                combo = QtWidgets.QComboBox()
                combo.addItems(options)
                combo.currentIndexChanged.connect(self.completeChanged)
                self.flay.addRow(text, combo)
                self.comboboxes.append(combo)
    def isComplete(self):
        indexes = [combo.currentIndex() for combo in self.comboboxes]
        is_completed = all(index >= 1 for index in indexes) and any(
            index >= 3 for index in indexes
        )
        self.wizard().setProperty("indexes_selected", indexes)
        self.wizard().setProperty(
            "options_selected", [combo.currentText() for combo in self.comboboxes]
        )
        return is_completed
class FinalPage(QtWidgets.QWizardPage):
    def initializePage(self):
        print(self.wizard().property("indexes_selected"))
        print(self.wizard().property("options_selected"))
class Manager(QtWidgets.QWizard):
    def __init__(self, parent=None):
        super(Manager, self).__init__(parent)
        self.resize(500, 300)
        self.addPage(ChooseFile())
        self.addPage(ChooseColumns())
        self.addPage(FinalPage())
if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    w = Manager()
    w.show()
    sys.exit(app.exec_())
 
回答来源:stackoverflow