在QTableWidget中添加支持多选的QComboBox并显示

引言

在Qt开发中,QTableWidget是一个非常常用的组件,它提供了一个易于使用的表格控件。但是,在某些情况下,我们需要在表格中添加更复杂的控件,比如支持多选的QComboBox。本文将详细介绍如何在QTableWidget中添加一个支持多选的QComboBox,并提供完整的示例代码。

效果展示

 

步骤概述

  1. 定义自定义表格项,主要用于显示复选框
  2. 自定义的多选ComboBox类
  3. 自定义委托类,用于表格中的多选ComboBox代码展示如下

代码展示如下

#include <QApplication>  // 包含QApplication类,用于所有Qt应用程序
#include <QWidget>        // 包含QWidget类,基本的UI对象容器
#include <QTableWidget>   // 包含QTableWidget类,用于显示表格
#include <QCheckBox>      // 包含QCheckBox类,用于显示复选框
#include <QComboBox>      // 包含QComboBox类,用于显示下拉列表框
#include <QHBoxLayout>    // 包含QHBoxLayout类,水平布局
#include <QLineEdit>      // 包含QLineEdit类,单行文本输入框
#include <QStandardItemModel> // 包含QStandardItemModel类,数据模型支持复选框等项
#include <QStandardItem>  // 包含QStandardItem类,可存储数据的单元项
#include <QItemDelegate>  // 包含QItemDelegate类,用于定制表格单元的显示与编辑方式

// 定义自定义表格项,主要用于显示复选框
class CheckBoxItem : public QTableWidgetItem {
public:
    CheckBoxItem() : QTableWidgetItem() {
        setCheckState(Qt::Unchecked);  // 初始化时设置复选框为未选中状态
    }
};

// 自定义的多选ComboBox类
class MultiComboBox : public QComboBox {
public:
    MultiComboBox(QWidget *parent = nullptr) : QComboBox(parent) {
        setEditable(true);  // 设置ComboBox为可编辑
        QLineEdit *lineEdit = new QLineEdit(this);  // 创建一个新的LineEdit
        lineEdit->setReadOnly(true);  // 设置LineEdit为只读,防止直接编辑
        setLineEdit(lineEdit);  // 将LineEdit设置为ComboBox的编辑器
    }

    // 添加选项到ComboBox
    void addItem(const QString &text) {
        QStandardItem *item = new QStandardItem(text);  // 创建一个新的标准项
        item->setFlags(Qt::ItemIsUserCheckable | Qt::ItemIsEnabled);  // 设置项为可检查并启用
        item->setData(Qt::Unchecked, Qt::CheckStateRole);  // 设置项默认为未勾选
        static_cast<QStandardItemModel *>(model())->appendRow(item);  // 将项添加到模型
    }

    // 获取当前已选择的所有项的文本
    QString currentText() const {
        QStringList selectedItems;
        int count = model()->rowCount();  // 获取模型中的行数
        for (int i = 0; i < count; ++i) {
            QStandardItem *item = static_cast<QStandardItemModel *>(model())->item(i);
            if (item->data(Qt::CheckStateRole).toInt() == Qt::Checked) {
                selectedItems.append(item->text());  // 如果项被选中,则添加到结果列表
            }
        }
        return selectedItems.join("、");  // 将结果列表中的文本用顿号连接并返回
    }
};

// 自定义委托类,用于表格中的多选ComboBox
class MultiComboBoxDelegate : public QItemDelegate {
public:
    MultiComboBoxDelegate(QObject *parent = nullptr) : QItemDelegate(parent) {}

    // 创建编辑器,用于编辑表格单元
    QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &,
                          const QModelIndex &) const override {
        MultiComboBox *editor = new MultiComboBox(parent);  // 创建MultiComboBox作为编辑器
        editor->addItem("跑步");  // 添加选项到下拉列表
        editor->addItem("乒乓球");
        editor->addItem("篮球");
        editor->addItem("足球");
        return editor;  // 返回创建的编辑器
    }

    // 设置编辑器显示数据
    void setEditorData(QWidget *editor, const QModelIndex &index) const override {
        QString value = index.model()->data(index, Qt::EditRole).toString();  // 获取当前单元的数据
        MultiComboBox *comboBox = static_cast<MultiComboBox*>(editor);
        comboBox->lineEdit()->setText(value);  // 设置编辑器显示当前数据
    }

    // 更新模型数据
    void setModelData(QWidget *editor, QAbstractItemModel *model,
                      const QModelIndex &index) const override {
        MultiComboBox *comboBox = static_cast<MultiComboBox*>(editor);
        QString value = comboBox->currentText();  // 从编辑器获取当前文本
        model->setData(index, value, Qt::EditRole);  // 更新模型中的数据
    }
};

// 主函数
int main(int argc, char *argv[]) {
    QApplication app(argc, argv);

    QWidget *window = new QWidget;  // 创建一个窗口
    QHBoxLayout *layout = new QHBoxLayout;  // 创建一个水平布局

    QTableWidget *table = new QTableWidget(10, 3, window);  // 创建一个10行3列的表格
    table->setHorizontalHeaderLabels(QStringList() << "序号" << "是否住校" << "爱好");  // 设置表头

    // 设置第二列使用复选框代理,第三列使用多选下拉框代理
    table->setItemDelegateForColumn(1, new CheckBoxDelegate());  // 第二列
    table->setItemDelegateForColumn(2, new MultiComboBoxDelegate());  // 第三列

    // 初始化表格数据
    for (int i = 0; i < 10; ++i) {
        table->setItem(i, 0, new QTableWidgetItem(QString::number(i + 1)));  // 设置序号
        CheckBoxItem *checkBoxItem = new CheckBoxItem();  // 创建复选框项
        table->setItem(i, 1, checkBoxItem);  // 在第二列设置复选框项
        table->setItem(i, 2, new QTableWidgetItem());  // 第三列预留给多选下拉框
    }

    layout->addWidget(table);  // 将表格添加到布局
    window->setLayout(layout);  // 设置窗口的布局
    window->show();  // 显示窗口

    return app.exec();  // 开始事件循环
}

要实现这个功能,你需要对 table widget 进行自定义,具体步骤如下: 1. 设置 table widget 的行数和列数; 2. 在第一列中添加一个 QCheckBox 组件,通过 setCellWidget() 方法将其添加到 table widget 中; 3. 在第二列中添加一个 QComboBox 组件,通过 setCellWidget() 方法将其添加到 table widget 中; 4. 通过遍历 table widget 中的每一行,获取第一列的 QCheckBox 组件,设置其为可中状态; 5. 通过遍历 table widget 中的每一行,获取第二列的 QComboBox 组件,添加项; 6. 在 table widget 中添加一个按钮,用于获取用户择的数据。 下面是一个示例代码,你可以参考一下: ```python from PySide6.QtCore import Qt from PySide6.QtWidgets import QApplication, QTableWidget, QTableWidgetItem, QComboBox, QCheckBox, QPushButton, QVBoxLayout, QWidget class MultiSelectComboBoxTableWidget(QTableWidget): def __init__(self, parent=None): super().__init__(parent) self.setColumnCount(2) self.setRowCount(3) self.setHorizontalHeaderLabels(["Multi-Select", "Single-Select"]) for i in range(self.rowCount()): checkbox = QCheckBox() self.setCellWidget(i, 0, checkbox) combobox = QComboBox() combobox.addItems(["Option 1", "Option 2", "Option 3"]) self.setCellWidget(i, 1, combobox) checkbox.stateChanged.connect(self.on_checkbox_state_changed) self.button = QPushButton("Get Selected Data") self.button.clicked.connect(self.on_button_clicked) layout = QVBoxLayout() layout.addWidget(self) layout.addWidget(self.button) widget = QWidget() widget.setLayout(layout) self.selected_data = [] def on_checkbox_state_changed(self, state): checkbox = self.sender() row = self.indexAt(checkbox.pos()).row() if state == Qt.Checked: self.selected_data.append((row, self.cellWidget(row, 1).currentText())) else: self.selected_data.remove((row, self.cellWidget(row, 1).currentText())) def on_button_clicked(self): print(self.selected_data) if __name__ == '__main__': app = QApplication([]) widget = MultiSelectComboBoxTableWidget() widget.show() app.exec() ``` 这个示例代码中创建了一个名为 MultiSelectComboBoxTableWidget 的 table widget,其中第一列为,第二列为下拉单。同时还添加了一个按钮用于获取用户择的数据。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值