实现UI层面的属性添加和删除

This commit is contained in:
duanshengchao 2025-03-27 21:01:25 +08:00
parent a3dcbf4233
commit 8cb6fdd5ae
8 changed files with 152 additions and 37 deletions

View File

@ -64,7 +64,7 @@ public:
void removeRecord(int);
//展示列控制
void setVisibleColumns(const QStringList& columns);
//void setVisibleColumns(const QStringList& columns);
void triggerSyncSignal();
@ -73,6 +73,13 @@ signals:
void showMessage(MessageDialogType,const QString&,const QString&);
private:
struct FieldInfo //字段信息
{
QString originalName; //数据库中的字段命名
QString displayName; //对外展示的名称
QString dataType = "unknown type"; //数据类型
};
struct RowData
{
//QSqlRecord record;
@ -80,6 +87,7 @@ private:
EditState state = Clean;
};
void iniDisplayField();
void loadPageData(); // 加载当前页数据
void updateTotalCount(); // 更新总记录数
@ -88,7 +96,7 @@ private:
ModelAttributeGroup m_modelAttributeGroup;
PaginationInfo m_paginationInfo;
QStringList m_visibleColumns;
QList<FieldInfo> m_displayField;
QList<RowData> m_currentPageData;
QHash<int, RowData> m_modifiedRows; //key:global row number
};

View File

@ -30,6 +30,9 @@ private slots:
void onSyncDataStatus(bool, const PaginationInfo&);
void onShowMessage(MessageDialogType,const QString&,const QString&);
void onBtnClicked_addRecord();
void onBtnClicked_removeRecord();
private:
int tabIndex(const QString&);

View File

@ -12,29 +12,32 @@ AttributeTableDelegate::~AttributeTableDelegate()
void AttributeTableDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const
{
if(index.column() == 0)
{
QString text = index.data(Qt::DisplayRole).toString();
if(text.contains("-") && m_tableView && m_tableView->model()) //删除项,整行画一条红线
{
int row = index.row();
for(int col = 0; col < m_tableView->model()->columnCount(); col++)
{
QModelIndex index = m_tableView->model()->index(row, col);
QRect rect = m_tableView->visualRect(index);
painter->save();
painter->setPen(Qt::red);
painter->drawLine(rect.x(), rect.y() + rect.height()*0.5, rect.x() + rect.width(), rect.y() + rect.height()*0.5); //painter属于view所以要以view的坐标系为标准
painter->restore();
QStyledItemDelegate::paint(painter, option, index);
}
}
}
else if (index.data(Qt::UserRole + 1).toBool())
//先执行默认绘制(包括背景、文本等基础元素)
QStyledItemDelegate::paint(painter, option, index);
//处理加粗字体逻辑(在基础绘制之上叠加)
if(/*index.column() == 0 || */index.data(Qt::UserRole + 100).toBool())
{
QStyleOptionViewItem opt = option;
initStyleOption(&opt, index);
opt.font.setBold(true);
//opt.palette.setColor(QPalette::Text, Qt::red);
QStyledItemDelegate::paint(painter, opt, index);
}
//最后绘制删除线(确保位于最顶层)
if(m_tableView && m_tableView->model())
{
QModelIndex numberIndex = m_tableView->model()->index(index.row(), 0);
QString text = numberIndex.data(Qt::DisplayRole).toString();
if(text.contains("-"))
{
QRect rect = m_tableView->visualRect(index);
painter->save();
painter->setPen(Qt::red);
painter->drawLine(rect.left(), rect.y() + rect.height()*0.5, rect.right(), rect.y() + rect.height()*0.5); //painter属于view所以要以view的坐标系为标准
painter->restore();
}
}
}

View File

@ -12,7 +12,7 @@ AttributeTableModel::AttributeTableModel(const ModelAttributeGroup& modelAttribu
m_paginationInfo.currentPage = 1;
m_paginationInfo.totalEntries = 0;
m_visibleColumns << "attribute" << "attribute_name" << "data_type_id" << "length_precision" << "default_value";
iniDisplayField();
}
AttributeTableModel::~AttributeTableModel()
@ -24,7 +24,7 @@ QModelIndex AttributeTableModel::index(int row, int column, const QModelIndex& p
return QModelIndex();
int dataCol = column - 1;
if(dataCol >= m_visibleColumns.count())
if(dataCol >= m_displayField.count())
return QModelIndex();
return createIndex(row, column);
@ -92,6 +92,12 @@ bool AttributeTableModel::setData(const QModelIndex &index, const QVariant &valu
if (role != Qt::EditRole || index.column() == 0)
return false;
// QModelIndex numberIndex = createIndex(index.row(), 0);
// QString text = numberIndex.data(Qt::DisplayRole).toString();
// qDebug() << text;
// if(text.contains("-")) //删除状态不可编辑
// return false;
int row = index.row();
int globalRow = (m_paginationInfo.currentPage - 1) * m_paginationInfo.entriesPerPage + row;
int dataCol = index.column() - 1; //第一列显示了行号
@ -116,7 +122,7 @@ QVariant AttributeTableModel::headerData(int section, Qt::Orientation orientatio
return role == Qt::DisplayRole ? "No." : QVariant();
else
{
return m_visibleColumns.value(section - 1);
return m_displayField.value(section - 1).displayName;
}
}
return QAbstractTableModel::headerData(section, orientation, role);
@ -129,17 +135,48 @@ int AttributeTableModel::rowCount(const QModelIndex& parent) const
int AttributeTableModel::columnCount(const QModelIndex &) const
{
return m_visibleColumns.isEmpty() ? 0 : m_visibleColumns.count() + 1;
return m_displayField.isEmpty() ? 0 : m_displayField.count() + 1;
}
Qt::ItemFlags AttributeTableModel::flags(const QModelIndex &index) const
{
QModelIndex numberIndex = createIndex(index.row(), 0);
QString text = numberIndex.data(Qt::DisplayRole).toString();
Qt::ItemFlags flags = QAbstractTableModel::flags(index);
if (index.column() != 0) //行号列不能编辑
if (index.column() != 0 || !text.contains("-")) //行号列不能编辑
flags = flags | Qt::ItemIsEditable;
return flags;
}
void AttributeTableModel::iniDisplayField()
{
FieldInfo field1;
field1.originalName = "attribute";
field1.displayName = QString::fromWCharArray(L"属性类别");
m_displayField.append(field1);
FieldInfo field2;
field2.originalName = "attribute_name";
field2.displayName = QString::fromWCharArray(L"属性名称");
m_displayField.append(field2);
FieldInfo field3;
field3.originalName = "data_type_id";
field3.displayName = QString::fromWCharArray(L"数据类型");
m_displayField.append(field3);
FieldInfo field4;
field4.originalName = "length_precision";
field4.displayName = QString::fromWCharArray(L"数据精度");
m_displayField.append(field4);
FieldInfo field5;
field5.originalName = "default_value";
field5.displayName = QString::fromWCharArray(L"默认值");
m_displayField.append(field5);
}
void AttributeTableModel::loadPageData()
{
m_currentPageData.clear();
@ -152,8 +189,11 @@ void AttributeTableModel::loadPageData()
beginResetModel();
QStringList columns;
for(int i = 0; i < m_displayField.count(); i++)
columns << m_displayField.at(i).originalName;
QString strSQL = QString("SELECT %1 FROM %2 LIMIT %3 OFFSET %4")
.arg(m_visibleColumns.join(", "))
.arg(columns.join(", "))
.arg(m_tableName)
.arg(m_paginationInfo.entriesPerPage)
.arg((m_paginationInfo.currentPage - 1) * m_paginationInfo.entriesPerPage);
@ -164,7 +204,7 @@ void AttributeTableModel::loadPageData()
{
RowData data;
//data.record = query.record();
for(int i = 0; i < m_visibleColumns.count(); i++)
for(int i = 0; i < m_displayField.count(); i++)
{
data.values.append(query.value(i));
}
@ -287,7 +327,7 @@ void AttributeTableModel::insertRecord(int row)
RowData newRow;
newRow.state = New;
newRow.values.resize(m_visibleColumns.count());
newRow.values.resize(m_displayField.count());
int globalRow = (m_paginationInfo.currentPage - 1) * m_paginationInfo.entriesPerPage + row;
m_modifiedRows[globalRow] = newRow;
@ -307,22 +347,26 @@ void AttributeTableModel::removeRecord(int row)
if(g_msgDlgBtn == btn_No)
return;
beginRemoveRows(QModelIndex(), row, row);
int globalRow = (m_paginationInfo.currentPage - 1) * m_paginationInfo.entriesPerPage + row;
m_modifiedRows[globalRow].state = Deleted;
if(m_currentPageData.at(row).state == New) //新添加未提交的记录
/*if(m_currentPageData.at(row).state == New) //新添加未提交的记录,直接删除
{
beginRemoveRows(QModelIndex(), row, row);
m_modifiedRows.remove(globalRow);
m_currentPageData.removeAt(row);
endRemoveRows();
}
else
else*/ //整行画红线进行标记
{
m_currentPageData[row].state = Deleted;
m_modifiedRows[globalRow] = m_currentPageData[row];
}
m_currentPageData.removeAt(row);
m_modifiedRows[globalRow].state = Deleted;
QModelIndex topLeft = createIndex(row, 0);
QModelIndex bottomRight = createIndex(row, columnCount() - 1);
emit dataChanged(topLeft, bottomRight, {Qt::DisplayRole});
}
endRemoveRows();
}
void AttributeTableModel::triggerSyncSignal()

View File

@ -1,4 +1,6 @@
#include "attributeView.h"
#include "attributeTableDelegate.h"
#include <QHeaderView>
#include <QVBoxLayout>
AttributeView::AttributeView(const ModelAttributeGroup& modelAttributeGroup, QWidget* parent, const QString& connection, const QString& tableName)
@ -8,9 +10,15 @@ AttributeView::AttributeView(const ModelAttributeGroup& modelAttributeGroup, QWi
, m_modelAttributeGroup(modelAttributeGroup)
{
m_tableView = new QTableView(this);
m_tableView->verticalHeader()->setVisible(false);
m_tableView->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft | Qt::AlignVCenter);
m_attributeTableModel = new AttributeTableModel(m_modelAttributeGroup, this, m_connection, m_attributeTable);
m_tableView->setModel(m_attributeTableModel);
AttributeTableDelegate* delegate = new AttributeTableDelegate(m_tableView, m_tableView);
m_tableView->setItemDelegate(delegate);
m_vLayout = new QVBoxLayout(this);
m_vLayout->setSpacing(0);
m_vLayout->setContentsMargins(0, 0, 0, 0);

View File

@ -13,6 +13,9 @@ DatabaseBrowser::DatabaseBrowser(QWidget *parent)
connect(ui->tabWidget, &QTabWidget::tabCloseRequested, this, &DatabaseBrowser::onTabCloseRequested);
connect(ui->tabWidget, &QTabWidget::currentChanged, this, &DatabaseBrowser::onCurrentTabChanged);
connect(ui->btnAdd, &QPushButton::clicked, this, &DatabaseBrowser::onBtnClicked_addRecord);
connect(ui->btnRemove, &QPushButton::clicked, this, &DatabaseBrowser::onBtnClicked_removeRecord);
}
DatabaseBrowser::~DatabaseBrowser()
@ -114,6 +117,43 @@ void DatabaseBrowser::onCurrentTabChanged(int index)
}
}
void DatabaseBrowser::onBtnClicked_addRecord()
{
QWidget* widget = ui->tabWidget->currentWidget();
AttributeView* attributeView = qobject_cast<AttributeView*>(widget);
if(attributeView)
{
QTableView* view = attributeView->view();
AttributeTableModel* model = attributeView->model();
if(view && model)
{
int row = model->rowCount(); //当前插入都是在最后一行
/*QModelIndex currentIndex = view->currentIndex();
if(currentIndex.row() != -1)
row = currentIndex.row();*/
model->insertRecord(row);
}
}
}
void DatabaseBrowser::onBtnClicked_removeRecord()
{
QWidget* widget = ui->tabWidget->currentWidget();
AttributeView* attributeView = qobject_cast<AttributeView*>(widget);
if(attributeView)
{
QTableView* view = attributeView->view();
AttributeTableModel* model = attributeView->model();
if(view && model)
{
QModelIndex currentIndex = view->currentIndex();
int row = currentIndex.row();
if( row != -1)
model->removeRecord(row);
}
}
}
void DatabaseBrowser::onSyncDataStatus(bool hasModifiedData, const PaginationInfo& paginationInfo)
{
ui->btnSave->setEnabled(!hasModifiedData);

View File

@ -37,7 +37,7 @@ void QTableWidgetHoverDelegate::paint(QPainter* painter, const QStyleOptionViewI
int col = index.column();
QTableWidgetItem* item = m_tableWiget->item(row, col);
QRect rect = m_tableWiget->visualItemRect(item);
qDebug() << row << ", " << col << " optionRect:" << option.rect << " visualItemRect:" << rect;
//qDebug() << row << ", " << col << " optionRect:" << option.rect << " visualItemRect:" << rect;
painter->save();
painter->setPen(Qt::red);
painter->drawLine(rect.x(), rect.y() + rect.height()*0.5, rect.x() + rect.width(), rect.y() + rect.height()*0.5); //painter属于view所以要以view的坐标系为标准

View File

@ -44,6 +44,15 @@ QTabBar::close-button:hover {
}
QTabBar::close-button:pressed {
border-image: url(:/img/images/btn_close_pressed.png);
}
QHeaderView
{
background-color: rgb(235, 235, 235);
}
QHeaderView::section
{
}</string>
</property>
<property name="currentIndex">