PyQt5:填充组合框与从表中的微件

PyQt5:填充组合框与从表中的微件

问题描述:

在这里,我有我的表窗口小部件,用户将在稍后补项目:PyQt5:填充组合框与从表中的微件

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? 我正在考虑某种循环,但不知道如何实现它。 我已经为对话框窗口和表格窗口小部件类创建了类。

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_()) 
+0

你试过我的回答吗?它已经做到了你想要的。目前,它从*一个*表中填充两个组合框,但可以很容易地更改为每个表使用不同的表。另一个答案旨在做一些完全不同的事情,即用组合框填充表格中的所有项目,而不是一列。 – ekhumoro

+0

@ekhumoro感谢您的回答!是的,我做过了。但它没有为我第一次解决。但我看到你编辑它,所以我现在也试着尝试。由于某种原因,第一次组合框未填满。也许我把它整合错了。 – akeg

一条有效的途径将数据传递到一个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_()) 
+0

你的代码打开了这两个窗口,它完美地结合在一起,但是当我试图将它包含在我的整个项目中时,它不起作用smh – akeg

+0

我添加了完整的代码,所以你可以更好地理解问题的出处 – akeg

+0

@akeg我有已经纠正它,测试它并告诉我它是否适合你。 – eyllanesc

可以set the model在组合框从表插件的型号,然后assign a specific column的组合框使用。这会自动更新组合框,以便在表格小部件的第一列显示任何项目,无论何时发生更改。排序过滤器可用于删除任何空的项目。

为了得到这个工作,你的代码将需要看起来像这样:

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)