簡體   English   中英

PyQt5:使用表格小部件中的項目填充組合框

[英]PyQt5: Fill combo-boxes with items from a table-widget

在這里,我有我的桌面小部件,用戶稍后將填寫:

class Ui_Form(object):
    def setupUi(self, Form):
        Form.setObjectName("Form")
        Form.resize(238, 260)
        self.tableWidget = QtWidgets.QTableWidget(Form)
        self.tableWidget.setGeometry(QtCore.QRect(10, 10, 221, 241))
        self.tableWidget.setObjectName("tableWidget")
        self.tableWidget.setColumnCount(2)
        self.tableWidget.setRowCount(7)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setVerticalHeaderItem(0, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setVerticalHeaderItem(1, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setVerticalHeaderItem(2, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setVerticalHeaderItem(3, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setVerticalHeaderItem(4, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setVerticalHeaderItem(5, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setVerticalHeaderItem(6, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(0, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(1, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setItem(0, 0, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setItem(0, 1, item)

        self.retranslateUi(Form)
        QtCore.QMetaObject.connectSlotsByName(Form)

這是我的對話窗口,其中包含一個組合框:

class Ui_Dialog(object):
    def setupUi(self, Dialog):
        Dialog.setObjectName("Dialog")
        Dialog.resize(281, 176)
        self.comboBox = QtWidgets.QComboBox(Dialog)
        self.comboBox.setGeometry(QtCore.QRect(90, 10, 71, 22))
        self.comboBox.setObjectName("comboBox")
        self.comboBox.addItem("")
        self.comboBox_2 = QtWidgets.QComboBox(Dialog)
        self.comboBox_2.setGeometry(QtCore.QRect(10, 10, 71, 22))
        self.comboBox_2.setObjectName("comboBox_2")
        self.comboBox_2.addItem("")
        self.dateTimeEdit = QtWidgets.QDateTimeEdit(Dialog)
        self.dateTimeEdit.setGeometry(QtCore.QRect(10, 60, 194, 22))
        self.dateTimeEdit.setObjectName("dateTimeEdit")
        self.label_2 = QtWidgets.QLabel(Dialog)
        self.label_2.setGeometry(QtCore.QRect(10, 40, 91, 16))
        self.label_2.setObjectName("label_2")
        self.lineEdit = QtWidgets.QLineEdit(Dialog)
        self.lineEdit.setGeometry(QtCore.QRect(150, 110, 113, 20))
        self.lineEdit.setObjectName("lineEdit")
        self.label_3 = QtWidgets.QLabel(Dialog)
        self.label_3.setGeometry(QtCore.QRect(150, 90, 121, 16))
        self.label_3.setObjectName("label_3")
        self.lineEdit_2 = QtWidgets.QLineEdit(Dialog)
        self.lineEdit_2.setGeometry(QtCore.QRect(10, 110, 113, 20))
        self.lineEdit_2.setObjectName("lineEdit_2")
        self.label_4 = QtWidgets.QLabel(Dialog)
        self.label_4.setGeometry(QtCore.QRect(10, 90, 111, 16))
        self.label_4.setObjectName("label_4")
        self.pushButton = QtWidgets.QPushButton(Dialog)
        self.pushButton.setGeometry(QtCore.QRect(150, 140, 111, 23))
        self.pushButton.setObjectName("pushButton")
        self.pushButton_2 = QtWidgets.QPushButton(Dialog)
        self.pushButton_2.setGeometry(QtCore.QRect(10, 140, 111, 23))
        self.pushButton_2.setObjectName("pushButton_2")

        self.retranslateUi(Dialog)
        QtCore.QMetaObject.connectSlotsByName(Dialog)

那么,如何使用Table Widget中的項目准確填充comboBox_2? 我正在考慮某種循環,但不知道如何實現它。 我已經為Dialog窗口和Table Widget類創建了類。

class Dialog(QtWidgets.QDialog, Ui_Dialog):
    def __init__(self, parent=None):
        QtWidgets.QDialog.__init__(self, parent)
        self.setupUi(self)
        # cancel
        self.pushButton_2.clicked.connect(self.reject)
        # accept
        self.pushButton.clicked.connect(self.accept)
        self.dateTimeEdit.setDisplayFormat("d/M/yy hh:mm")

class Masters(QtWidgets.QDialog,Ui_Form):
    def __init__(self, parent=None):
        QtWidgets.QDialog.__init__(self, parent)
        self.setupUi(self)

完整代碼(不包括gui)

class Dialog(QtWidgets.QDialog, Ui_Dialog):
    def __init__(self, parent=None):
        QtWidgets.QDialog.__init__(self, parent)
        self.setupUi(self)
        # cancel
        self.pushButton_2.clicked.connect(self.reject)
        # accept
        self.pushButton.clicked.connect(self.accept)
        self.dateTimeEdit.setDisplayFormat("d/M/yy hh:mm")

    def data(self):
        master = self.comboBox_2.currentText()
        service = self.comboBox.currentText()
        name = self.lineEdit_2.text()
        contact_number = self.lineEdit.text()
        time = self.dateTimeEdit.time()
        return master, service, name, contact_number, time

    class Services(QtWidgets.QDialog,Ui_SForm):
        def __init__(self, parent=None):
            QtWidgets.QDialog.__init__(self, parent)
            self.setupUi(self)

class Masters(QtWidgets.QDialog,Ui_Form):
    def __init__(self, parent=None):
        QtWidgets.QDialog.__init__(self, parent)
        self.setupUi(self)

class Table2ListProxyModel(QtCore.QAbstractProxyModel):
    def __init__(self, parent=None):
        QtCore.QAbstractProxyModel.__init__(self, parent)
        self.mapping = []

    def setSourceModel(self, sourceModel):
        sourceModel.dataChanged.connect(lambda: self.fixModel())
        QtCore.QAbstractProxyModel.setSourceModel(self, sourceModel)
        self.fixModel()

    def mapFromSource(self, sourceIndex):
        if sourceIndex.isValid():
            key = self.mapping.index((sourceIndex.row(), sourceIndex.column()))
            return self.index(key, 0)
        return QtCore.QModelIndex()

    def mapToSource(self, proxyIndex):
        if proxyIndex.isValid():
            r, c = self.mapping[proxyIndex.row()]
            return self.sourceModel().index(r, c)
        return QtCore.QModelIndex()

    def rowCount(self, parent=QtCore.QModelIndex()):
        return len(self.mapping)

    def columnCount(self, parent=QtCore.QModelIndex()):
        return 1

    def index(self, row, column, parent=QtCore.QModelIndex()):
        return self.createIndex(row, column)

    def parent(self, child):
        return QtCore.QModelIndex()

    def fixModel(self):
        self.layoutAboutToBeChanged.emit()
        self.mapping = []
        for c in range(self.sourceModel().columnCount()):
            for r in range(self.sourceModel().rowCount()):
                ix = self.sourceModel().index(r, c)
                data = self.sourceModel().data(ix)
                if data is not None and data != "":
                    self.mapping.append((r, c))
        self.layoutChanged.emit()

class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
    def __init__(self, parent=None):
        QtWidgets.QMainWindow.__init__(self, parent)
        self.setupUi(self)
        self.addclient.clicked.connect(self.onAddClient)
        self.uslugi.clicked.connect(self.AddService)
        self.mastera.clicked.connect(self.AddMaster)

    def AddService(self):
        services = Services(self)
        services.show()

    def AddMaster(self):
        masters = Masters(self)
        masters.show()

    def onAddClient(self):
        dialog = Dialog(self)
        if dialog.exec_() == QtWidgets.QDialog.Accepted:
            master, service, name, contact_number, time = dialog.data()
            row = int(QtCore.QTime(8, 0).secsTo(time)/(30*60))
            if row >= 0:
                for k, text in enumerate([master, service, name, contact_number]):
                self.tableWidget.setItem(row, k+1, QtWidgets.QTableWidgetItem(text))




if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    dialog = Dialog()
    master = Masters()
    proxy = Table2ListProxyModel()
    proxy.setSourceModel(master.tableWidget.model())
    dialog.comboBox_2.setModel(proxy)
    w = MainWindow()
    w.show()
    sys.exit(app.exec_())

您可以在表格小部件的組合框中將模型設置為模型 ,然后為要使用的組合框指定特定列 這將自動更新組合框,以便在表單小部件更改時顯示其中的任何項目。 排序過濾器可用於刪除任何空項。

為了實現這一點,您的代碼需要看起來像這樣:

class Dialog(QtWidgets.QDialog, Ui_Dialog):
    def __init__(self, parent=None):
        QtWidgets.QDialog.__init__(self, parent)
        ...
        # set the model   
        model = QtCore.QSortFilterProxyModel(self)
        model.setSourceModel(parent.tableWidget.model())
        model.setFilterRegExp('.*\S.*')
        model.setFilterKeyColumn(1)
        model.setDynamicSortFilter(True)
        self.comboBox_2.setModel(model)
        self.comboBox_2.setModelColumn(1)
        model.sort(1, QtCore.Qt.AscendingOrder)

將數據傳遞給QComboBox一種強大方法是使用模型,因為這個QComboBox有方法setModel() ,但是這種情況的一個不便之處在於你只能從QTableWidget的列中獲取數據,這是解決這個問題的一種方法。不方便的是使用代理將模型作為表轉換為列表:

class Table2ListProxyModel(QAbstractProxyModel):
    def __init__(self, parent=None):
        QAbstractProxyModel.__init__(self, parent)
        self.mapping = []

    def setSourceModel(self, sourceModel):
        sourceModel.dataChanged.connect(lambda: self.fixModel())
        QAbstractProxyModel.setSourceModel(self, sourceModel)
        self.fixModel()

    def mapFromSource(self, sourceIndex):
        if sourceIndex.isValid():
            key = self.mapping.index((sourceIndex.row(), sourceIndex.column()))
            return self.index(key, 0)
        return QModelIndex()

    def mapToSource(self, proxyIndex):
        if proxyIndex.isValid():
            r, c = self.mapping[proxyIndex.row()]
            return self.sourceModel().index(r, c)
        return QModelIndex()

    def rowCount(self, parent=QModelIndex()):
        return len(self.mapping)

    def columnCount(self, parent=QModelIndex()):
        return 1

    def index(self, row, column, parent=QModelIndex()):
        return self.createIndex(row, column)

    def parent(self, child):
        return QModelIndex()

    def fixModel(self):
        self.layoutAboutToBeChanged.emit()
        self.mapping = []
        for c in range(self.sourceModel().columnCount()):
            for r in range(self.sourceModel().rowCount()):
                ix = self.sourceModel().index(r, c)
                data = self.sourceModel().data(ix)
                if data is not None and data != "":
                    self.mapping.append((r, c))
        self.layoutChanged.emit()


class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
    def __init__(self, parent=None):
        QtWidgets.QMainWindow.__init__(self, parent)
        self.setupUi(self)
        self.addclient.clicked.connect(self.onAddClient)
        self.uslugi.clicked.connect(self.AddService)
        self.mastera.clicked.connect(self.AddMaster)
        self.masters = Masters(self)
        proxy = Table2ListProxyModel()
        proxy.setSourceModel(self.masters.tableWidget.model())
        self.dialog = Dialog(self)
        self.dialog.comboBox_2.setModel(proxy)

    def AddMaster(self):
        self.masters.show()

    def AddService(self):
        services = Services(self)
        services.show()

    def onAddClient(self):
        if self.dialog.exec_() == QtWidgets.QDialog.Accepted:
            master, service, name, contact_number, time = self.dialog.data()
            row = int(QtCore.QTime(8, 0).secsTo(time) / (30 * 60))
            if row >= 0:
                for k, text in enumerate([master, service, name, contact_number]):
                    self.tableWidget.setItem(row, k + 1, QtWidgets.QTableWidgetItem(text))


if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    w = MainWindow()
    w.show()
    sys.exit(app.exec_())

編輯:

class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
    def __init__(self, parent=None):
        QtWidgets.QMainWindow.__init__(self, parent)
        self.setupUi(self)
        self.addclient.clicked.connect(self.onAddClient)
        self.mastera.clicked.connect(self.AddMaster)
        self.masters = Masters(self)
        self.services = Services(self)
        self.dialog = Dialog(self)

        proxy = QtCore.QSortFilterProxyModel()
        proxy.setSourceModel(self.masters.tableWidget.model())
        proxy.setFilterRegExp(".*\S.*")
        self.dialog.comboBox_2.setModel(proxy)

        proxy2 = QtCore.QSortFilterProxyModel()
        proxy2.setFilterRegExp(".*\S.*")
        proxy2.setSourceModel(self.services.tableWidget.model())
        self.dialog.comboBox.setModel(proxy2)
        self.dialog.comboBox.setModelColumn(1)

    def AddService(self):
        self.services.show()

    def AddMaster(self):
        self.masters.show()

    def onAddClient(self):
        if self.dialog.exec_() == QtWidgets.QDialog.Accepted:
            master, service, name, contact_number, time = self.dialog.data()
            row = int(QtCore.QTime(8, 0).secsTo(time) / (30 * 60))
            if row >= 0:
                for k, text in enumerate([master, service, name, contact_number]):
                    self.tableWidget.setItem(row, k + 1, QtWidgets.QTableWidgetItem(text))


if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    w = MainWindow()
    w.show()
    sys.exit(app.exec_())

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM