如何使用QCombobox选择来更新QTableView单元格?

尼莫XXX

我想向某些QTableView行中的特定单元格添加一个委托QComboBox委托。我找到了几篇有关如何添加委托的文章,但没有有关使用QComboBox选择项更新单元的示例。

这是我到目前为止所拥有的:

main.ui

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>Dialog</class>
 <widget class="QDialog" name="Dialog">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>350</width>
    <height>239</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>Dialog</string>
  </property>
  <widget class="QWidget" name="formLayoutWidget">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>341</width>
     <height>231</height>
    </rect>
   </property>
   <layout class="QFormLayout" name="formLayout">
    <item row="0" column="1">
     <widget class="QPushButton" name="btnPopulate">
      <property name="text">
       <string>Populate Table</string>
      </property>
     </widget>
    </item>
    <item row="1" column="1">
     <widget class="QTableView" name="tableView"/>
    </item>
   </layout>
  </widget>
 </widget>
 <resources/>
 <connections/>
</ui>

test.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys, os
from PyQt5 import uic, QtWidgets
from PyQt5.QtGui import QStandardItemModel
from PyQt5.QtWidgets import QDialog, QComboBox, QApplication

class GUI(QDialog):

    def __init__(self):
        super(GUI, self).__init__()
        dirname = os.path.dirname(os.path.abspath(__file__))
        uic.loadUi(os.path.join(dirname,'main.ui'), self)
        # button
        self.btnPopulate.clicked.connect(self.populate)
        # table model
        self.header = ['col1', 'col2', 'col3']
        self.QSModel = QStandardItemModel()
        self.QSModel.setColumnCount(3)
        self.QSModel.setHorizontalHeaderLabels(self.header)
        self.tableView.setModel(self.QSModel)
        # combobox delegate
        self.cbDelegate = QComboBox()
        self.cbDelegate.addItems(['choice1', 'choice2'])

    def populate(self):
        row = self.QSModel.rowCount()
        for x in range(0, 7):
            self.QSModel.insertRow(row)
            self.QSModel.setData(self.QSModel.index(row, 0), 'data')
            self.QSModel.item(row, 0).setEditable(True)
            self.QSModel.setData(self.QSModel.index(row, 1), 'data')
            self.QSModel.item(row, 1).setEditable(True)
            # add combobox delegate to even rows
            if x % 2 == 0:
                print('Delegate added.')
                index = self.tableView.model().index(row, 1)
                self.tableView.setIndexWidget(index, self.cbDelegate)
            self.QSModel.setData(self.QSModel.index(row, 2), 'data')
            self.QSModel.item(row, 1).setEditable(True)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = GUI()
    window.show()
    sys.exit(app.exec_())

但是,当我单击“填充表”按钮时,只有第一行的第二个单元格显示为QComboBox。

  1. 我该如何更改代码以在第0、2、4和6行或任何此行中显示QComboBox。(是否需要显示QComboBox取决于到达范围行中第一个单元格的值。)

  2. 我需要使用哪种方法用QComboBox选项替换单元格内容?

永乐

我该如何更改代码以在第0、2、4和6行或任何此行中显示QComboBox。(是否需要显示QComboBox取决于到达范围行中第一个单元格的值。)

这个问题使您只能看到QComboBox,这是因为您仅创建了一个QComboBox,要解决该问题,必须为要在其中建立它们的每个单元格创建一个QComboBox。

我需要使用哪种方法用QComboBox选项替换单元格内容?

您必须将适当的信号连接到模型的setData()方法,我们可以使用QModelIndex,但是这样做很危险,因为在删除,移动或插入项目时可以更改它,因此在这种情况下,最好使用QPersistentModelIndex您必须使用信号currentIndexChanged

在此示例中,我将使用QModelIndex

def populate(self):
    row = self.QSModel.rowCount()
    for x in range(7):
        self.QSModel.insertRow(row)
        self.QSModel.setData(self.QSModel.index(row, 0), 'data')
        self.QSModel.item(row, 0).setEditable(True)
        self.QSModel.setData(self.QSModel.index(row, 1), 'data')
        self.QSModel.item(row, 1).setEditable(True)
        # add combobox delegate to even rows
        if x % 2 == 0:
            index = self.tableView.model().index(row, 1)
            cbDelegate = QComboBox()
            pix = QPersistentModelIndex(index)
            cbDelegate.currentIndexChanged[str].connect(lambda txt, pix=pix:self.tableView.model().setData(QModelIndex(pix), txt))
            cbDelegate.addItems(['choice1', 'choice2'])
            self.tableView.setIndexWidget(index, cbDelegate)
        self.QSModel.setData(self.QSModel.index(row, 2), 'data')
        self.QSModel.item(row, 1).setEditable(True)

在此示例中,我将使用QStandartItem

def populate(self):
    row = self.QSModel.rowCount()
    for x in range(7):
        self.QSModel.insertRow(row)
        self.QSModel.setData(self.QSModel.index(row, 0), 'data')
        self.QSModel.item(row, 0).setEditable(True)
        self.QSModel.setData(self.QSModel.index(row, 1), 'data')
        self.QSModel.item(row, 1).setEditable(True)
        if x % 2 == 0:
            item = self.tableView.model().item(row, 1)
            cbDelegate = QComboBox()
            cbDelegate.currentIndexChanged[str].connect(item.setText)
            cbDelegate.addItems(['choice1', 'choice2'])
            self.tableView.setIndexWidget(item.index(), cbDelegate)
        self.QSModel.setData(self.QSModel.index(row, 2), 'data')
        self.QSModel.item(row, 1).setEditable(True)

执行类似操作的另一种方法是使用委托,为此,我们创建了一个继承自的类QStyledItemDelegate

class ComboBoxDelegate(QStyledItemDelegate):
    def paint(self, painter, option, index):
        if index.row()%2 == 0:
            opt = QStyleOptionComboBox()
            opt.rect = option.rect 
            opt.currentText = index.data()
            QApplication.style().drawComplexControl(QStyle.CC_ComboBox, opt, painter)
            QApplication.style().drawControl(QStyle.CE_ComboBoxLabel, opt, painter)
        else:
            QStyledItemDelegate.paint(self, painter, option, index)

    def createEditor(self, parent, option, index):
        if index.row()%2 == 0:
            combobox = QComboBox(parent)
            options = ['choice1', 'choice2']
            if index.data() not in options:
                combobox.addItem(index.data())
            combobox.addItems(options)
            return combobox
        return QStyledItemDelegate.createEditor(self, parent, option, index)

    def setEditorData(self, editor, index):
        if isinstance(editor, QComboBox):
            text = index.data()
            ix = editor.findText(text)
            if ix > 0:
                editor.setCurrentIndex(ix)
            else:
                index.model().setData(index, editor.currentText())
        else:
            QStyledItemDelegate.setEditorData(self, editor, index)

    def setModelData(self, editor, model, index):
        if isinstance(editor, QComboBox):
            model.setData(index, editor.currentText())
        else:
            QStyledItemDelegate.setModelData(self, editor, model, index)

class GUI(QDialog):
    def __init__(self):
        super(GUI, self).__init__()
        dirname = os.path.dirname(os.path.abspath(__file__))
        uic.loadUi(os.path.join(dirname,'main.ui'), self)
        self.btnPopulate.clicked.connect(self.populate)
        self.header = ['col1', 'col2', 'col3']
        self.QSModel = QStandardItemModel()
        self.QSModel.setColumnCount(3)
        self.QSModel.setHorizontalHeaderLabels(self.header)
        self.tableView.setModel(self.QSModel)
        self.tableView.setItemDelegateForColumn(1, ComboBoxDelegate(self.tableView))
        self.populate()

    def populate(self):
        row = self.QSModel.rowCount()
        for x in range(7):
            for i, value in enumerate(['data1', 'data2', 'data3']):
                self.QSModel.setItem(row+x, i, QStandardItem(value))
                self.QSModel.item(row+x, i).setEditable(True)

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

始终在QTableView的单元格中显示QComboBox

如何使用pyside在QtableView单元格中设置数据

如何使用 IF 选择单元格?

如何在Google表格的单元格中显示默认的当前日期,在该单元格中使用数据验证来选择日期?

QTableView强制一个单元格的选择

如何使用 INDEX 和 MATCH 来基于单元格?

如何在vba中使用集合来更新另一个单元格与一个单元格的值进行比较

当我从tableView中选择一个单元格时,如何使用navigationController来显示WebView?

如何使用jQuery选择相邻的表格单元格

如何跟踪使用NSIndexPath选择的单元格?

如何使用javascript选择或检索excelsheet的单元格数据?

如何使用选择单元格范围变量

使用列表框选择来选择并转到单元格

如何使用HTML格式的可单击单元格制作快速的QTableView?

使用自定义QAbstractTableModel创建Qtableview后如何为单元格着色

Excel VBA根据选择来选择多个单元格

如何从单元格 QTableView 中获取纯文本

如何使用Python更新连续矩阵的单元格?

如何获取JTable复选框单元格以使用外部更新选择所有按钮助记符

如何通过单击单元格中的按钮来删除tableView中的单元格?使用coreData

如何按功能选择单元格

如何选择QTableWidget的多个单元格?

如何通过鼠标按下和拖动来关闭jtable单元格选择

如何根据下拉列表中的值选择来更新ngx-datatable中下一个单元格的值?

在 xlwings 中总是使用异步 UDF 来更新单元格是否有意义?

是否可以使用当前行的非空单元格的数量来更新列?

使用查询更新单元格的内容

在QTableView中编辑单元格后使用TAB键前进时,如何避免使用编辑模式?

如何使用MVVM / RxSwift根据其他单元格的值更新表视图的单元格?