gpt4 book ai didi

c++ - QStandardItemModel & 绑定(bind)到自定义对象

转载 作者:行者123 更新时间:2023-12-02 10:22:47 31 4
gpt4 key购买 nike

我尝试使用 Qt 示例的城市标准项并将其调整为我的示例。我有一个奇怪的结果:

这是我的用户类:

class User{
public:
User();

QString getFirstname() const;
void setFirstname(const QString &value);

QString getLastname() const;
void setLastname(const QString &value);

int getAge() const;
void setAge(int value);

private:
QString firstname;
QString lastname;
int age;
};

我已经声明了一个usermodel.h:
class UserModel: public QStandardItemModel
{
Q_OBJECT
public:
UserModel(QList<User> users, QObject *parent = Q_NULLPTR);

QHash<int, QByteArray> roleNames() const;
};

下面是构造函数和 roleNames 函数的实现:
enum ItemRoles {
FirstnameRole,
LastnameRole,
AgeRole,
};


UserModel::UserModel(QList<User> users, QObject *parent) : QStandardItemModel(parent)
{

//this->setItemRoleNames(roleNames());
this->setColumnCount(3);
for (auto user: users) {
QStandardItem *item = new QStandardItem();
item->setData(user.getFirstname(), FirstnameRole);
item->setData(user.getLastname(), LastnameRole);
item->setData(user.getAge(), AgeRole);
appendRow(item);
}

setSortRole(FirstnameRole);
}


QHash<int, QByteArray> UserModel::roleNames() const
{
QHash<int, QByteArray> mapping = QStandardItemModel::roleNames();

mapping[FirstnameRole] = "firstname";
mapping[LastnameRole] = "lastname";
mapping[AgeRole] = "age";

return mapping;
}

我的表格 View 仅显示使用该功能添加的最后一个角色: item->setData(user.getFirstname(), FirstnameRole);
如果它最后添加的年龄,它的年龄显示...
有什么线索吗?

最佳答案

比方说你真的需要自定义模型并希望扩展现有模型。由于您的数据采用表格形式,我建议使用 QAbstractTableModel作为基类。

所以让我们来上课:

class UserModel: public QAbstractTableModel
{
Q_OBJECT
QList<User> _users;
public:
UserModel(QList<User> users, QObject *parent = Q_NULLPTR) : QAbstractTableModel(parent), _users(users){}

如您所见,该类本身存储了在构建时给出的用户列表。构造函数本身只对列表进行复制初始化。

然后你需要提供这些实现,至少:
int rowCount(const QModelIndex &) const override
{
return _users.size();
}
int columnCount(const QModelIndex &) const override
{
return 3;
}
QVariant data(const QModelIndex &index, int role) const override
{
if(role == Qt::DisplayRole)
{
User user = _users.at(index.row());
QVariant data[] = { user.getFirstname(), user.getLastname() , user.getAge() };
return data[index.column()];
}
return {};
}

columnCount是常数并且总是返回 3, rowCount将返回用户列表中的项目数。
data实现,根据索引的行列,检查传入的索引并返回一个值,传入的 角色 .
当 View 调用 data 时,理解这一点很重要。通过 role等于 Qt::DisplayRole ,函数应该返回将在单元格中显示的数据 (index.row(), index.column()) ,在我们的例子中:三个 User 之一的数据成员。

重新实现 sort 非常有用功能以及,即
void sort(int column, Qt::SortOrder order) override
{
auto fnSort = [](const User & u1, const User & u2){ return u1.getFirstname() < u2.getFirstname(); };
auto lnSort = [](const User & u1, const User & u2){ return u1.getLastname() < u2.getLastname(); };
auto agSort = [](const User & u1, const User & u2){ return u1.getAge() < u2.getAge(); };

std::function<bool (const User &, const User &)> sortFn[] = {fnSort, lnSort, agSort};
std::sort(_users.begin(), _users.end(), sortFn[column]);

if(order == Qt::DescendingOrder)
{
std::reverse(_users.begin(), _users.end());
}
}

这样您就可以让用户按列排序,如预期的那样:
myTableView->setModel(new UserModel(list));
myTableView->model()->sort(2, Qt::DescendingOrder); //sort by first age, in descending order

如果出于某种原因,您想使用自定义角色,请让您的枚举如下所示:
enum ItemRoles {
FirstnameRole = Qt::UserRole,
LastnameRole,
AgeRole,
};

Qt::UserRole 开始(为此目的)确保您的角色不会与内置角色发生冲突。

请注意,上面的代码是为了 建议 一个可能的解决方案,它不是 解决方案本身(并且缺少许多重要功能,例如边界检查和内存管理)。

关于c++ - QStandardItemModel & 绑定(bind)到自定义对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59369248/

31 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com