How to get selected items from QComboBox to be displayed in QTableWidget in PyQt5? (QComboBox has checkbox to pick items)

时间秒杀一切 提交于 2021-02-11 17:19:45

问题


I have QTableWidget in which I have QComboBox in each row for particular column. My each QCombobox has multiple values with checkboxes. I want to display selected item/s from each combobox in the next respective column 'SelectedMonths' in the same row and remove them when unchecked (Vice-versa).

Until now I have Script ready which gives me what all items have been checked/unchecked but I dont know how to get the index of the row for which combobox is activated.

Snippet to get the workflow

Sample Code:

Code Generated by QtDesigner: Demo.py

from PyQt5 import QtCore, QtGui, QtWidgets

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(464, 291)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.tableWidget = QtWidgets.QTableWidget(self.centralwidget)
        self.tableWidget.setGeometry(QtCore.QRect(30, 30, 411, 221))
        self.tableWidget.setRowCount(1)
        self.tableWidget.setColumnCount(2)
        self.tableWidget.setObjectName("tableWidget")
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setItem(0, 0, item)
        item = QtWidgets.QTableWidgetItem()
        self.tableWidget.setItem(0, 1, item)
        self.tableWidget.horizontalHeader().setVisible(False)
        self.tableWidget.verticalHeader().setVisible(False)
        MainWindow.setCentralWidget(self.centralwidget)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

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

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        __sortingEnabled = self.tableWidget.isSortingEnabled()
        self.tableWidget.setSortingEnabled(False)
        item = self.tableWidget.item(0, 0)
        item.setText(_translate("MainWindow", "Select Months"))
        item = self.tableWidget.item(0, 1)
        item.setText(_translate("MainWindow", "Selected Months"))
        self.tableWidget.setSortingEnabled(__sortingEnabled)


if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())

Code which I have written: DemoCode.py

from PyQt5 import QtWidgets, QtGui
from PyQt5.QtWidgets import QTableWidgetItem
from PyQt5.QtGui import QStandardItem, QStandardItemModel
from PyQt5.QtCore import Qt
from datetime import date
from dateutil.relativedelta import relativedelta

from Demo import Ui_MainWindow

def CheckableCombobox(combo, options):
    model = QStandardItemModel(len(options), 1)
    firstItem = QtGui.QStandardItem("SelectMonths")
    firstItem.setBackground(QtGui.QBrush(QtGui.QColor(200, 200, 200)))
    firstItem.setSelectable(False)
    model.setItem(0, 0, firstItem)
    for i, area in enumerate(options):
        item = QStandardItem(area)
        item.setFlags(Qt.ItemIsUserCheckable | Qt.ItemIsEnabled)
        item.setData(Qt.Unchecked, Qt.CheckStateRole)
        model.setItem(i+1, 0, item)
    combo.setModel(model)

class DemoCode(QtWidgets.QMainWindow, Ui_MainWindow):                    
    def __init__(self):
        super(DemoCode, self).__init__()
        self.setupUi(self)  

        self.rowPosition = self.tableWidget.rowCount()
        for row in range(0,3):
            self.tableWidget.insertRow(self.rowPosition)
            for column in range(0,2):
                if column == 0:
                    self.ComboBox = QtWidgets.QComboBox()
                    dtStart = date.today()
                    self.Monthlist = []
                    for n in range(1, 5):
                        self.Monthlist.append((dtStart + relativedelta(months=-n)).strftime('1-%b-%Y'))
                    CheckableCombobox(self.ComboBox, self.Monthlist)
                    self.ComboBox.model().itemChanged.connect(self.on_itemChanged)
                    self.tableWidget.setCellWidget(self.rowPosition, column, self.ComboBox)
                elif column == 1:
                    item = QTableWidgetItem('')
                    self.tableWidget.setItem(self.rowPosition, column, item)

            self.rowPosition += 1

        self.tableWidget.setColumnWidth(1,150)

    def on_itemChanged(self, item):
        current_state = item.data(Qt.CheckStateRole)
        print(current_state, item.text())

if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    window = DemoCode()    
    window.show()
    sys.exit(app.exec_())

回答1:


You should find a way to keep track of the row for each combo model, so that you can set the item text accordingly.

Note that I changed your code logic a bit, as there were some conceptual mistakes:

  • don't set instance attributes if they are not required: all those self.rowPosition, self.monthList, etc, change everytime the for loop cycles, and you don't need them after that;
  • avoid using uppercase names for variables and functions
  • the month list is always the same, build it before the for cycle instead of computing it each time
  • instead of setting the model to the combo in the function, make it return the model

Edit: added copy function after comment request

def createModel(options):
    model = QStandardItemModel(len(options), 1)
    firstItem = QtGui.QStandardItem("SelectMonths")
    firstItem.setBackground(QtGui.QBrush(QtGui.QColor(200, 200, 200)))
    firstItem.setSelectable(False)
    model.setItem(0, 0, firstItem)
    for i, area in enumerate(options):
        item = QStandardItem(area)
        item.setFlags(Qt.ItemIsUserCheckable | Qt.ItemIsEnabled)
        item.setData(Qt.Unchecked, Qt.CheckStateRole)
        model.setItem(i+1, 0, item)
    return model

class DemoCode(QtWidgets.QMainWindow, Ui_MainWindow):                    
    def __init__(self):
        super(DemoCode, self).__init__()
        self.

来源:https://stackoverflow.com/questions/60626964/how-to-get-selected-items-from-qcombobox-to-be-displayed-in-qtablewidget-in-pyqt

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!