表格是Qt最重量级的控件之一,另外一个重量级控件就是树。QTableWidget是成熟的表格控件,它有默认的模型QTableModel(继承自QAbstractTableModel),QTableWidget本身继承自QTableView。
本文通过多个示例展示QTableWidget表格的丰富的使用方法。
表格中动态创建下拉框等自定义控件
以下是一个示例,通过实现一个QStyledItemDelegate的子类,来提供自定义的表格代理控件,然后在表格中设置该代理。
最终实现的效果就是双击表格第一列的单元格都会在单元格内创建下拉框编辑控件,并且在交互完成后控件内的值会同步到表格中。
如果要实现表格的不同列的编辑控件不一样,比如有的通过下拉框编辑,有的通过拨轮编辑,就可以通过在ItemDelegate的createEditor方法中去创建这些不同的控件。
#ifndef ITEMDELEGATE_H
#define ITEMDELEGATE_H
#include <QStyledItemDelegate>
class ItemDelegate : public QStyledItemDelegate
{
Q_OBJECT
public:
explicit ItemDelegate(QObject *parent = nullptr);
// QAbstractItemDelegate interface
public:
QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const;
void setEditorData(QWidget *editor, const QModelIndex &index) const;
void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const;
};
#endif // ITEMDELEGATE_H
#include "itemdelegate.h"
#include <QtWidgets>
ItemDelegate::ItemDelegate(QObject *parent)
: QStyledItemDelegate{parent}
{
}
QWidget *ItemDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
if(index.column()==0)
{//当双击表格第1列的单元格时,会创建下拉框
QComboBox* cbx=new QComboBox(parent);
cbx->addItems({"100","200"});
return cbx;
}
return QStyledItemDelegate::createEditor(parent,option,index);
}
void ItemDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
if(index.column()==0)
{//将单元格的值写入到代理控件中
QComboBox* cbx=qobject_cast<QComboBox*>(editor);
if(cbx!=nullptr)
{
QString value=index.model()->data(index,Qt::EditRole).toString();
cbx->setCurrentText(value);
}
}
else
QStyledItemDelegate::setEditorData(editor,index);
}
void ItemDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{
if(index.column()==0)
{
QComboBox* cbx=qobject_cast<QComboBox*>(editor);
if(cbx!=nullptr)
{
model->setData(index,cbx->currentText(),Qt::EditRole);
}
}
else
QStyledItemDelegate::setModelData(editor,model,index);
}
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
{
this->resize(800,600);
QTableWidget* tb=new QTableWidget;
tb->setRowCount(3);
tb->setColumnCount(5);
tb->setItemDelegate(new ItemDelegate);
this->setCentralWidget(tb);
}