首先在ui界面拖一个tableView
ui->tableView->setModel(mission_model);
然后设置model的qss,并用view绑定model
void SettingWidget::init_missionmodel(QString plane_type, QString mission_name)
{
if(mission_model)
delete mission_model;
mission_model = new MissionModel(plane_type, mission_name, this);
connect(mission_model, SIGNAL(missionFollow_send(QVariant, QVariant)), this, SLOT(getMissionFollow(QVariant, QVariant)));
connect(mission_model, SIGNAL(namePlate_show(QVariant)), this, SLOT(getNamePlate(QVariant)));
ui->tableView->setModel(mission_model);
int row_count = mission_model->rowCount();
for (int i = 0; i < row_count; i++)
{
QModelIndex index = mission_model->index(i, 4);
QPushButton *button = static_cast<QPushButton*>(index.internalPointer());
ui->tableView->setIndexWidget(index, button);
}
ui->tableView->horizontalHeader()->resizeSection(0,80);
ui->tableView->horizontalHeader()->setSectionResizeMode(1, QHeaderView::Stretch);
ui->tableView->horizontalHeader()->setSectionResizeMode(2, QHeaderView::Stretch);
ui->tableView->horizontalHeader()->setSectionResizeMode(3, QHeaderView::Stretch);
ui->tableView->horizontalHeader()->setSectionResizeMode(4, QHeaderView::Stretch);
//ui->tableView->setSelectionBehavior(QAbstractItemView::SelectRows);
ui->tableView->setSelectionMode(QAbstractItemView::SingleSelection);
ui->tableView->setContextMenuPolicy(Qt::CustomContextMenu);
ui->tableView->verticalHeader()->hide();
// ui->tableView->horizontalHeader()->setStyleSheet("QHeaderView::section{background:#3a3e46;color: white;}");
}
MissionModel.h
#ifndef MISSIONMODEL_H
#define MISSIONMODEL_H
#include <QAbstractTableModel>
#include <QJsonObject>
#include <QJsonArray>
#include <QPushButton>
#include <QMap>
class MissionModel : public QAbstractTableModel
{
Q_OBJECT
public:
MissionModel(QString plane_name_t, QString mission_name, QObject *parent = nullptr);
virtual ~MissionModel() override;
// Header:
QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
// Basic functionality:
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
QModelIndex index(int row, int column, 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) override;
void refresh();
Qt::ItemFlags flags(const QModelIndex & index) const override ;
QJsonObject getItemData(int index);
void init_data();
signals:
void missionFollow_send(QVariant missionName, QVariant missionColor);
void namePlate_show(QVariant missionName);
private:
QList<QString> headtitle;
QJsonArray dataList;
QMap<int,QPushButton* > color_buttons;
QString plane_name;
QString mission_name;
QString file_name;
};
#endif // MISSIONMODEL_H
MissionModel.cpp
#include "missionmodel.h"
#include <QCoreApplication>
#include <QFile>
#include <QJsonArray>
#include <QMessageBox>
#include <QColorDialog>
#include "global.h"
#include "./ui/util/jsontool.h"
MissionModel::MissionModel(QString plane_name_t, QString mission_name_t, QObject *parent)
: plane_name(plane_name_t), mission_name(mission_name_t), QAbstractTableModel(parent)
{
headtitle<< QStringLiteral("序号") << QStringLiteral("项目名称") << QStringLiteral("实时关注") << QStringLiteral("铭牌显示") << QStringLiteral("颜色");
init_data();
}
MissionModel::~MissionModel()
{
foreach (QPushButton* button, color_buttons.values()) {
delete button;
}
color_buttons.clear();
}
QVariant MissionModel::headerData(int section, Qt::Orientation orientation, int role) const
{
switch(role){
case Qt::DisplayRole:
{
if (orientation == Qt::Horizontal) {
return headtitle[section];
}
break;
}
// case Qt::FontRole:
// {
// QFont boldFont;
// boldFont.setBold(true);
// boldFont.setPixelSize(14);
// return boldFont;
// }
case Qt::TextAlignmentRole:
return Qt::AlignLeft + Qt::AlignVCenter;
break;
}
return QVariant();
}
int MissionModel::rowCount(const QModelIndex &parent) const
{
return dataList.size();
}
int MissionModel::columnCount(const QModelIndex &parent) const
{
return headtitle.size();
}
//在第4列放按钮
QModelIndex MissionModel::index(int row, int column, const QModelIndex &parent) const
{
if (column == 4)
{
return createIndex(row, column, color_buttons[row]);
}
else
return QAbstractTableModel::index(row, column, parent);
}
//在第 2,3 列放checkbox
Qt::ItemFlags MissionModel::flags(const QModelIndex &index) const
{
if (index.column() == 2 || index.column() == 3)
return Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable;
return QAbstractTableModel::flags(index);
}
//这里负责把数据显示到界面对应单元格
重点
setdata()的调用次数=row * col *31(枚举数)
有多少行就调用多少次。每一行有多少列就调用多少次。对每一个单元格的枚举调用多少次
如下图针对每个单元格的31哥枚举会调用31次data()
比如背景颜色,文本居中,文本颜色,显示内容,如果是checkbox,那么选中状态bool
Qt::TextAlignmentRole: Qt::DisplayRole: Qt::CheckStateRole:
enum ItemDataRole {
DisplayRole = 0,
DecorationRole = 1,
EditRole = 2,
ToolTipRole = 3,
StatusTipRole = 4,
WhatsThisRole = 5,
// Metadata
FontRole = 6,
TextAlignmentRole = 7,
BackgroundRole = 8,
ForegroundRole = 9,
#if QT_DEPRECATED_SINCE(5, 13) // ### Qt 6: remove me
BackgroundColorRole Q_DECL_ENUMERATOR_DEPRECATED = BackgroundRole,
TextColorRole Q_DECL_ENUMERATOR_DEPRECATED = ForegroundRole,
#endif
CheckStateRole = 10,
// Accessibility
AccessibleTextRole = 11,
AccessibleDescriptionRole = 12,
// More general purpose
SizeHintRole = 13,
InitialSortOrderRole = 14,
// Internal UiLib roles. Start worrying when public roles go that high.
DisplayPropertyRole = 27,
DecorationPropertyRole = 28,
ToolTipPropertyRole = 29,
StatusTipPropertyRole = 30,
WhatsThisPropertyRole = 31,
// Reserved
UserRole = 0x0100
};
QVariant MissionModel::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
return QVariant();
int row = index.row();
int col = index.column();
QJsonObject obj = dataList.at(row).toObject();
switch(role){
case Qt::DisplayRole:
{
switch (col) {
case 0:
return row + 1;
case 1:
return obj[headtitle.at(1)].toString();
case 2:
return obj[headtitle.at(2)].toString();
case 3:
return obj[headtitle.at(3)].toString();
case 4:
{
QPushButton *button = static_cast<QPushButton*>(index.internalPointer());
button->setText(obj[headtitle.at(4)].toString());
// button->setStyleSheet(QString("background-color: %1").arg(obj[headtitle.at(4)].toString()));
return obj[headtitle.at(4)].toString();
}
default:
break;
}
}
break;
case Qt::TextAlignmentRole:
{
if(col == 0)
return Qt::AlignCenter;
}
return Qt::AlignLeft + Qt::AlignVCenter;
break;
case Qt::ForegroundRole:
switch (col) {
case 1:
//return info.isLive? QVariant(QColor("#7ebdfd")):QVariant(QColor("#ee6666"));
break;
default:
break;
}
break;
case Qt::CheckStateRole:
{
QJsonObject obj = dataList.at(row).toObject();
if (index.column() == 2)
{
return obj[headtitle.at(2)].toBool() == true ? Qt::Checked : Qt::Unchecked;
}
else if (index.column() == 3)
{
return obj[headtitle.at(3)].toBool() == true ? Qt::Checked : Qt::Unchecked;
}
}
}
return QVariant();
}
bool MissionModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
if(!index.isValid())
return false;
int row = index.row();
int col = index.column();
QModelIndex m_index_name = this->index(row,1);
QModelIndex m_index_color = this->index(row,4);
QVariant missionName = this->data(m_index_name);
QVariant missionColor = this->data(m_index_color);
// if (role == Qt::CheckStateRole && (col == 2 || col == 3) )
// {
// QJsonObject obj = dataList[row].toObject();
// obj[headtitle.at(col)] = value == Qt::Checked;
// dataList[row] = obj;
// if( !JsonTool::save_json_file<QJsonArray>(file_name, dataList) )
// {
// QMessageBox::information( nullptr, QStringLiteral("修改失败"), QStringLiteral("修改失败"));
// }
// }
if (role == Qt::CheckStateRole && col == 2 )
{
QJsonObject obj = dataList[row].toObject();
obj[headtitle.at(col)] = value == Qt::Checked;
dataList[row] = obj;
if(obj[headtitle.at(2)].toBool() == true)
{
emit missionFollow_send(missionName, missionColor);
return true;
}
if( !JsonTool::save_json_file<QJsonArray>(file_name, dataList) )
{
QMessageBox::information( nullptr, QStringLiteral("修改失败"), QStringLiteral("修改失败"));
}
}
else if (role == Qt::CheckStateRole && col == 3 )
{
QJsonObject obj = dataList[row].toObject();
obj[headtitle.at(col)] = value == Qt::Checked;
dataList[row] = obj;
if(obj[headtitle.at(2)].toBool() == true)
{
emit namePlate_show(missionName);
return true;
}
if( !JsonTool::save_json_file<QJsonArray>(file_name, dataList) )
{
QMessageBox::information( nullptr, QStringLiteral("修改失败"), QStringLiteral("修改失败"));
}
}
return true;
}
void MissionModel::refresh()
{
beginResetModel();
//...
endResetModel();
}
//这个是我自己写的
QJsonObject MissionModel::getItemData(int index)
{
return dataList.at(index).toObject();
}
void MissionModel::init_data()
{
file_name = QString("%1/config/fc_config/%2_%3.json").arg(QCoreApplication::applicationDirPath()).arg(plane_name).arg(mission_name);
if(QFile::exists(file_name))
{
QJsonArray json_array = JsonTool::load_jsonarray_file(file_name);
//dataList. .clear();
for(int i = 0; i < json_array.size(); i++)
{
dataList.append(json_array.at(i).toObject());
}
}
else
{
//dataList.clear();
QString tmp_file_name = QString("%1/config/fc_config/%2.json").arg(QCoreApplication::applicationDirPath()).arg(plane_name);
QJsonObject obj = JsonTool::load_json_file(tmp_file_name);
QStringList keys = obj.keys();
if(keys.empty())
{
qWarning()<<"read a empty obj: "<<tmp_file_name<<endl;
return;
}
QJsonArray json_array;
foreach (QString key, keys)
{
QJsonObject item;
item.insert(QStringLiteral("项目名称"), key);
item.insert(QStringLiteral("实时关注"), false);
item.insert(QStringLiteral("铭牌显示"), false);
item.insert(QStringLiteral("颜色"), "#ffffff");
json_array.append(item);
dataList.append(item);
}
JsonTool::save_json_file<QJsonArray>(file_name, json_array);
}
color_buttons.clear();
for(int i = 0; i<dataList.size(); i++)
{
QPushButton* button_p = new QPushButton();
connect(button_p, &QPushButton::clicked, this, [=](){
QColor color = QColorDialog::getColor();
if (color.isValid()) {
QPushButton *button = qobject_cast<QPushButton *>(sender());
if (button)
{
// button->setStyleSheet(QString("background-color: %1").arg(color.name()));
QJsonObject obj = dataList[i].toObject();
obj[headtitle.at(4)] = color.name();
dataList[i] = obj;
if( !JsonTool::save_json_file<QJsonArray>(file_name, dataList) )
{
QMessageBox::information( nullptr, QStringLiteral("修改失败"), QStringLiteral("修改失败"));
}
}
}
});
color_buttons.insert(i, button_p);
}
}