我如何使用for循环中多个QComboBox中的任何一个的最小索引?

问题描述 投票:1回答:1

我有一个QWizard,它读取CSV文件的列标题,并让用户为每列选择所需的内容。在此向导的第二页中,我将组合框添加到一个for循环中,该循环遍历CSV的列名。 所有组合框均为必填字段。但是,另一个限制是,在用户可以按“下一步”之前,必须至少选择其中一个以选择3或更高(在我的MWE中为c1或c2)。

除了self.NextButton.setEnabled(False),我还根据isComplete示例和completeChanged问题尝试使用thisthis,但由于是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_())
python python-3.x pyqt pyqt5
1个回答
1
投票

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_())
© www.soinside.com 2019 - 2024. All rights reserved.