引言
在Qt开发中,QTableWidget是一个非常常用的组件,它提供了一个易于使用的表格控件。但是,在某些情况下,我们需要在表格中添加更复杂的控件,比如支持多选的QComboBox。本文将详细介绍如何在QTableWidget中添加一个支持多选的QComboBox,并提供完整的示例代码。
效果展示
步骤概述
- 定义自定义表格项,主要用于显示复选框
- 自定义的多选ComboBox类
- 自定义委托类,用于表格中的多选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(); // 开始事件循环
}