qt c++ delegate
时间: 2024-08-26 18:01:59 浏览: 26
在Qt C++ 中,Delegate是一种强大的工具,它用于将数据模型(如QAbstractItemModel)的数据映射到界面控件上,简化了表格视图(QTableView)、列表视图(QListView)等组件与实际业务数据之间的交互。Delegate允许你自定义单元格的显示内容、编辑行为以及事件处理,而无需直接操作视图底层的数据源。
使用Delegate的好处包括:
1. **易于维护**:它将UI逻辑从视图代码中分离出来,使得界面更新更独立于数据模型变化。
2. **提高性能**:由于数据绑定是间接的,不会频繁地触发模型的数据更新,提高了应用程序运行效率。
3. **灵活性**:Delegate支持复杂的定制,比如条件渲染、验证输入、计算结果展示等。
要在Qt中创建Delegate,通常步骤如下:
1. 创建`QStyledItemDelegate`的子类,并重写必要的方法,如`paint`和`sizeHint`。
2. 将 Delegate 绑定到视图的列上,通过设置`itemDelegate`属性。
3. 自定义样式和行为,如设置文本格式、响应点击事件等。
相关问题
QT C++ MVD 例子
以下是一个简单的 QT C++ MVD(Model-View-Delegate)例子:
Model.h:
```cpp
#ifndef MODEL_H
#define MODEL_H
#include <QAbstractListModel>
#include <QStringList>
class Model : public QAbstractListModel
{
Q_OBJECT
public:
explicit Model(QObject *parent = nullptr);
enum {
NameRole = Qt::UserRole,
AgeRole
};
// 声明 QAbstractListModel 纯虚函数
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
// 自定义函数
bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole) override;
Qt::ItemFlags flags(const QModelIndex &index) const override;
void addPerson(const QString &name, int age);
private:
struct Person {
QString name;
int age;
};
QList<Person> m_persons;
};
#endif // MODEL_H
```
Model.cpp:
```cpp
#include "Model.h"
Model::Model(QObject *parent)
: QAbstractListModel(parent)
{
}
int Model::rowCount(const QModelIndex &parent) const
{
Q_UNUSED(parent);
return m_persons.count();
}
QVariant Model::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
return QVariant();
const auto &person = m_persons.at(index.row());
switch (role) {
case Qt::DisplayRole:
case NameRole:
return person.name;
case AgeRole:
return person.age;
default:
break;
}
return QVariant();
}
bool Model::setData(const QModelIndex &index, const QVariant &value, int role)
{
if (!index.isValid() || role != Qt::EditRole)
return false;
auto &person = m_persons[index.row()];
switch (index.column()) {
case 0:
person.name = value.toString();
break;
case 1:
person.age = value.toInt();
break;
default:
return false;
}
emit dataChanged(index, index, {role});
return true;
}
Qt::ItemFlags Model::flags(const QModelIndex &index) const
{
auto flags = QAbstractListModel::flags(index);
if (index.isValid())
flags |= Qt::ItemIsEditable;
return flags;
}
void Model::addPerson(const QString &name, int age)
{
beginInsertRows(QModelIndex(), rowCount(), rowCount());
m_persons.append({name, age});
endInsertRows();
}
```
Delegate.h:
```cpp
#ifndef DELEGATE_H
#define DELEGATE_H
#include <QStyledItemDelegate>
class Delegate : public QStyledItemDelegate
{
Q_OBJECT
public:
explicit Delegate(QObject *parent = nullptr);
// 声明 QStyledItemDelegate 纯虚函数
QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
void setEditorData(QWidget *editor, const QModelIndex &index) const override;
void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const override;
void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
};
#endif // DELEGATE_H
```
Delegate.cpp:
```cpp
#include "Delegate.h"
#include <QLineEdit>
Delegate::Delegate(QObject *parent)
: QStyledItemDelegate(parent)
{
}
QWidget *Delegate::createEditor(QWidget *parent, const QStyleOptionViewItem &, const QModelIndex &) const
{
auto editor = new QLineEdit(parent);
return editor;
}
void Delegate::setEditorData(QWidget *editor, const QModelIndex &index) const
{
const auto &text = index.model()->data(index, Qt::EditRole).toString();
auto lineEdit = static_cast<QLineEdit *>(editor);
lineEdit->setText(text);
}
void Delegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
{
auto lineEdit = static_cast<QLineEdit *>(editor);
const auto &text = lineEdit->text();
model->setData(index, text, Qt::EditRole);
}
void Delegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &) const
{
editor->setGeometry(option.rect);
}
```
MainWindow.h:
```cpp
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
class Model;
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void on_addButton_clicked();
private:
Ui::MainWindow *ui;
Model *m_model;
};
#endif // MAINWINDOW_H
```
MainWindow.cpp:
```cpp
#include "MainWindow.h"
#include "ui_MainWindow.h"
#include "Model.h"
#include "Delegate.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow),
m_model(new Model(this))
{
ui->setupUi(this);
ui->tableView->setModel(m_model);
ui->tableView->setItemDelegate(new Delegate(this));
ui->tableView->setSelectionMode(QAbstractItemView::SingleSelection);
ui->tableView->setSelectionBehavior(QAbstractItemView::SelectRows);
ui->tableView->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_addButton_clicked()
{
const auto &name = ui->nameEdit->text();
const auto age = ui->ageSpinBox->value();
m_model->addPerson(name, age);
}
```
使用 QT Designer 创建一个 MainWindow.ui 界面,包含一个 QTableView 和两个 QLineEdit,一个 QSpinBox 和一个 QPushButton。
MainWindow.ui:
```
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>640</width>
<height>480</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralwidget">
<widget class="QTableView" name="tableView">
<geometry>
<rect>
<x>20</x>
<y>20</y>
<width>600</width>
<height>300</height>
</rect>
</geometry>
</widget>
<widget class="QLineEdit" name="nameEdit">
<geometry>
<rect>
<x>20</x>
<y>350</y>
<width>200</width>
<height>20</height>
</rect>
</geometry>
</widget>
<widget class="QSpinBox" name="ageSpinBox">
<geometry>
<rect>
<x>240</x>
<y>350</y>
<width>80</width>
<height>20</height>
</rect>
</geometry>
</widget>
<widget class="QPushButton" name="addButton">
<geometry>
<rect>
<x>340</x>
<y>350</y>
<width>80</width>
<height>20</height>
</rect>
</geometry>
<property name="text">
<string>Add</string>
</property>
</widget>
</widget>
</widget>
<resources/>
<connections/>
</ui>
```
最终效果如下:
![QT C++ MVD 例子](https://img-blog.csdnimg.cn/2021070509285015.png)
qt c++ tableview中的字体大小
在Qt C++的QTableView中设置字体大小,你可以通过继承自QAbstractItemDelegate并实现paintCell()函数来定制单元格的外观,包括字体。以下是步骤:
1. 创建自定义的item delegate类,例如`MyTableWidgetItemDelegate`,继承自`QAbstractItemDelegate`:
```cpp
class MyTableWidgetItemDelegate : public QAbstractItemDelegate {
public:
explicit MyTableWidgetItemDelegate(QObject *parent = nullptr)
: QAbstractItemDelegate(parent) {}
// ... 其他必要的构造函数和属性
protected:
void paint(QPainter *painter,
const QStyleOptionViewItem &option,
const QModelIndex &index) const override {
painter->setFont(QFont("Arial", 12)); // 设置字体大小为12点
// ... 继续绘制表格内容
super::paint(painter, option, index);
}
private:
// ... 如果需要,可以添加其他自定义样式处理
};
```
2. 将这个自定义delegate应用到QTableView上:
```cpp
QTableView *tableView = new QTableView(parent);
tableView->setItemDelegate(new MyTableWidgetItemDelegate(tableView));
```
在这里,字体大小是固定的12点,你可以根据需要调整`QFont`构造函数里的值。