qt5的mvc模型视图代理实现,其中model有9列数据,最多20行数据,数据总页数不超过20页。列数据依次为:点号,信息描述,遥信位,动作时间,复归时间,验收时间,确认状态,确认/取消,通道类型,其中1,2,3,8,9列数据初始化有数据,其他列为空。第8列数据是ico图标。初始化的时候只加载第一页数据。当有下一页数据来的时候,清除当前页的数据和内存,当前页数据某行数据改变时,颜色置高亮,更新当前行的空的其他数据,其中第8列数据更改图标,请思考一下,给出代码用例
时间: 2024-03-16 13:46:04 浏览: 58
以下是一个简单的示例代码,实现了基本的MVC模型视图代理功能。其中使用了QStandardItemModel作为数据模型,QTableView作为视图,QStyledItemDelegate作为代理。
在这个示例中,模型有9列数据,最多20行数据,每页显示5行数据。其中1,2,3,8,9列数据初始化有数据,其他列为空。第8列数据是ico图标(使用QIcon显示)。初始化的时候只加载第一页数据。当有下一页数据来的时候,清除当前页的数据和内存,当前页数据某行数据改变时,颜色置高亮,更新当前行的空的其他数据,其中第8列数据更改图标。
```cpp
#include <QtWidgets>
class MyDelegate : public QStyledItemDelegate
{
public:
MyDelegate(QObject *parent = nullptr) : QStyledItemDelegate(parent) {}
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override
{
// 如果是第8列数据,使用QIcon显示图标
if (index.column() == 7) {
QIcon icon = qvariant_cast<QIcon>(index.data());
if (!icon.isNull()) {
QRect rect = option.rect;
QSize size = rect.size();
int side = qMin(size.width(), size.height());
QRect iconRect(rect.x() + (size.width() - side) / 2, rect.y() + (size.height() - side) / 2, side, side);
icon.paint(painter, iconRect);
return;
}
}
QStyledItemDelegate::paint(painter, option, index);
}
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override
{
// 如果是第8列数据,返回QIcon的尺寸
if (index.column() == 7) {
QIcon icon = qvariant_cast<QIcon>(index.data());
if (!icon.isNull()) {
return icon.actualSize(option.rect.size());
}
}
return QStyledItemDelegate::sizeHint(option, index);
}
};
class MyModel : public QStandardItemModel
{
public:
MyModel(QObject *parent = nullptr) : QStandardItemModel(parent) {}
void loadPage(int page)
{
// 清除当前页的数据和内存
removeRows(0, rowCount());
// 模拟从数据库中获取数据
int totalRows = 20;
int rowsPerPage = 5;
int startRow = page * rowsPerPage;
int endRow = qMin(startRow + rowsPerPage, totalRows);
for (int i = startRow; i < endRow; i++) {
QList<QStandardItem *> items;
items << new QStandardItem(QString::number(i + 1)); // 点号
items << new QStandardItem("信息描述"); // 信息描述
items << new QStandardItem("遥信位"); // 遥信位
items << new QStandardItem("动作时间"); // 动作时间
items << new QStandardItem("复归时间"); // 复归时间
items << new QStandardItem("验收时间"); // 验收时间
items << new QStandardItem("确认状态"); // 确认状态
items << new QStandardItem(QIcon(":/icons/icon.png"), "确认/取消"); // 确认/取消
items << new QStandardItem("通道类型"); // 通道类型
appendRow(items);
}
}
};
class MyView : public QTableView
{
public:
MyView(QWidget *parent = nullptr) : QTableView(parent)
{
setSortingEnabled(false);
setSelectionBehavior(QAbstractItemView::SelectRows);
setSelectionMode(QAbstractItemView::SingleSelection);
setEditTriggers(QAbstractItemView::NoEditTriggers);
setHorizontalScrollMode(QAbstractItemView::ScrollPerPixel);
setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
MyDelegate *delegate = new MyDelegate(this);
setItemDelegate(delegate);
}
void setCurrentPage(int page)
{
if (page == m_currentPage) {
return;
}
m_currentPage = page;
m_model->loadPage(m_currentPage);
selectRow(0);
}
void setCurrentRow(int row)
{
QModelIndex index = m_model->index(row, 0);
if (index.isValid()) {
setCurrentIndex(index);
scrollTo(index, QAbstractItemView::PositionAtCenter);
}
}
void nextPage()
{
if (m_currentPage < m_totalPages - 1) {
setCurrentPage(m_currentPage + 1);
}
}
void prevPage()
{
if (m_currentPage > 0) {
setCurrentPage(m_currentPage - 1);
}
}
void updateCurrentRow(int col, const QVariant &data)
{
QModelIndex index = currentIndex();
if (index.isValid()) {
QStandardItem *item = m_model->itemFromIndex(index);
if (item) {
// 更新当前行的空的其他数据
for (int i = 0; i < m_model->columnCount(); i++) {
if (i != col && item->data().isNull()) {
item->setData(data, i);
}
}
// 更新第8列数据的图标
if (col == 7) {
item->setIcon(qvariant_cast<QIcon>(data));
}
// 颜色置高亮
QModelIndex topLeft = m_model->index(index.row(), 0);
QModelIndex bottomRight = m_model->index(index.row(), m_model->columnCount() - 1);
emit dataChanged(topLeft, bottomRight);
}
}
}
protected:
void keyPressEvent(QKeyEvent *event) override
{
switch (event->key()) {
case Qt::Key_Up:
if (currentIndex().row() == 0 && m_currentPage > 0) {
prevPage();
setCurrentRow(m_model->rowCount() - 1);
}
else {
QTableView::keyPressEvent(event);
}
break;
case Qt::Key_Down:
if (currentIndex().row() == m_model->rowCount() - 1 && m_currentPage < m_totalPages - 1) {
nextPage();
setCurrentRow(0);
}
else {
QTableView::keyPressEvent(event);
}
break;
default:
QTableView::keyPressEvent(event);
break;
}
}
private:
MyModel *m_model = new MyModel(this);
int m_currentPage = 0;
int m_totalPages = 20 / 5 + 1;
};
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
MyView view;
view.setCurrentPage(0);
view.show();
return app.exec();
}
```
在示例代码中,我们定义了三个类:MyDelegate,MyModel和MyView。MyDelegate是一个QStyledItemDelegate的子类,用于显示第8列数据的图标;MyModel是一个QStandardItemModel的子类,用于加载数据;MyView是一个QTableView的子类,用于显示数据。
在MyModel中,我们定义了一个loadPage方法,用于加载一页数据。在这个方法中,我们首先清除当前页的数据和内存,然后模拟从数据库中获取数据,添加到模型中。
在MyView中,我们定义了setCurrentPage,setCurrentRow,nextPage,prevPage和updateCurrentRow等方法。setCurrentPage方法用于设置当前页,loadPage方法将根据页码加载数据并更新视图。setCurrentRow方法用于设置当前行,将根据行号设置当前索引并滚动到中心位置。nextPage和prevPage方法用于切换到下一页和上一页,将使用setCurrentPage方法加载数据并选中第一行。updateCurrentRow方法用于更新当前行的数据,将更新除第8列以外的空数据,更新第8列的图标,将当前行颜色置高亮。
在MyView中,我们还重载了keyPressEvent方法,用于在到达当前页的边缘时自动切换到下一页或上一页。
阅读全文