添加自定义HeaderView,支持多行展示,支持每一行的样式设置,支持section大小随内自适配
This commit is contained in:
parent
8cb6fdd5ae
commit
90e0599dd9
|
|
@ -30,6 +30,7 @@ set(H_HEADER_FILES
|
||||||
include/settings.h
|
include/settings.h
|
||||||
include/tableWidgetHoverDelegate.h
|
include/tableWidgetHoverDelegate.h
|
||||||
include/customMenu.h
|
include/customMenu.h
|
||||||
|
include/multiLineHeaderView.h
|
||||||
include/modelInfoEditDialog.h
|
include/modelInfoEditDialog.h
|
||||||
include/sqlQueryExecutor.h
|
include/sqlQueryExecutor.h
|
||||||
include/attributeTableModel.h
|
include/attributeTableModel.h
|
||||||
|
|
@ -52,6 +53,7 @@ set(CPP_SOURCE_FILES
|
||||||
source/settings.cpp
|
source/settings.cpp
|
||||||
source/tableWidgetHoverDelegate.cpp
|
source/tableWidgetHoverDelegate.cpp
|
||||||
source/customMenu.cpp
|
source/customMenu.cpp
|
||||||
|
source/multiLineHeaderView.cpp
|
||||||
source/modelInfoEditDialog.cpp
|
source/modelInfoEditDialog.cpp
|
||||||
source/sqlQueryExecutor.cpp
|
source/sqlQueryExecutor.cpp
|
||||||
source/attributeTableModel.cpp
|
source/attributeTableModel.cpp
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@
|
||||||
#include "attributeTableModel.h"
|
#include "attributeTableModel.h"
|
||||||
|
|
||||||
class QVBoxLayout;
|
class QVBoxLayout;
|
||||||
|
class MultiLineHeaderView;
|
||||||
class AttributeView : public QWidget
|
class AttributeView : public QWidget
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
@ -31,6 +32,8 @@ private:
|
||||||
QTableView* m_tableView;
|
QTableView* m_tableView;
|
||||||
AttributeTableModel* m_attributeTableModel;
|
AttributeTableModel* m_attributeTableModel;
|
||||||
QVBoxLayout* m_vLayout;
|
QVBoxLayout* m_vLayout;
|
||||||
|
|
||||||
|
MultiLineHeaderView* m_multiLinHeader;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif //ATTRIBUTEVIEW_H
|
#endif //ATTRIBUTEVIEW_H
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,37 @@
|
||||||
|
#ifndef MULTILINEHEADERVIEW
|
||||||
|
#define MULTILINEHEADERVIEW
|
||||||
|
|
||||||
|
#include <QHeaderView>
|
||||||
|
|
||||||
|
struct HeaderLineStyle
|
||||||
|
{
|
||||||
|
QFont font = QFont("Microsoft YaHei", 9);
|
||||||
|
QColor color = QColor(26, 26, 26);
|
||||||
|
Qt::Alignment alignment = Qt::AlignLeft;
|
||||||
|
};
|
||||||
|
|
||||||
|
class MultiLineHeaderView : public QHeaderView
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit MultiLineHeaderView(Qt::Orientation orientation, QWidget* parent = nullptr);
|
||||||
|
|
||||||
|
void setLineSpacing(int);
|
||||||
|
void setBackgroundColor(QColor&);
|
||||||
|
void setBorderColor(QColor&);
|
||||||
|
void setSectionLineStyle(int, int, const HeaderLineStyle&); //设置某列的某行文字样式
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void paintSection(QPainter*, const QRect&, int) const override;
|
||||||
|
QSize sectionSizeFromContents(int) const override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QHash<int, QMap<int, HeaderLineStyle>> m_sectionStyles; //列号->(行号->样式)
|
||||||
|
HeaderLineStyle m_defaultStyle;
|
||||||
|
QColor m_bgColor; //背景颜色
|
||||||
|
QColor m_borderColor; //边框颜色
|
||||||
|
int m_linSpacing; //行间距
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //MULTILINEHEADERVIEW
|
||||||
|
|
@ -122,7 +122,11 @@ QVariant AttributeTableModel::headerData(int section, Qt::Orientation orientatio
|
||||||
return role == Qt::DisplayRole ? "No." : QVariant();
|
return role == Qt::DisplayRole ? "No." : QVariant();
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return m_displayField.value(section - 1).displayName;
|
QString headerText = m_displayField.value(section - 1).displayName;
|
||||||
|
if(!m_displayField.value(section - 1).dataType.isEmpty())
|
||||||
|
headerText = headerText + "\n" + m_displayField.value(section - 1).dataType;
|
||||||
|
|
||||||
|
return headerText;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return QAbstractTableModel::headerData(section, orientation, role);
|
return QAbstractTableModel::headerData(section, orientation, role);
|
||||||
|
|
@ -144,7 +148,7 @@ Qt::ItemFlags AttributeTableModel::flags(const QModelIndex &index) const
|
||||||
QString text = numberIndex.data(Qt::DisplayRole).toString();
|
QString text = numberIndex.data(Qt::DisplayRole).toString();
|
||||||
|
|
||||||
Qt::ItemFlags flags = QAbstractTableModel::flags(index);
|
Qt::ItemFlags flags = QAbstractTableModel::flags(index);
|
||||||
if (index.column() != 0 || !text.contains("-")) //行号列不能编辑
|
if (index.column() != 0 && !text.contains("-")) //行号列和处于删除状态的item不能编辑
|
||||||
flags = flags | Qt::ItemIsEditable;
|
flags = flags | Qt::ItemIsEditable;
|
||||||
return flags;
|
return flags;
|
||||||
}
|
}
|
||||||
|
|
@ -154,26 +158,31 @@ void AttributeTableModel::iniDisplayField()
|
||||||
FieldInfo field1;
|
FieldInfo field1;
|
||||||
field1.originalName = "attribute";
|
field1.originalName = "attribute";
|
||||||
field1.displayName = QString::fromWCharArray(L"属性类别");
|
field1.displayName = QString::fromWCharArray(L"属性类别");
|
||||||
|
field1.dataType = "character varying(128)";
|
||||||
m_displayField.append(field1);
|
m_displayField.append(field1);
|
||||||
|
|
||||||
FieldInfo field2;
|
FieldInfo field2;
|
||||||
field2.originalName = "attribute_name";
|
field2.originalName = "attribute_name";
|
||||||
field2.displayName = QString::fromWCharArray(L"属性名称");
|
field2.displayName = QString::fromWCharArray(L"属性名称");
|
||||||
|
field2.dataType = "character varying(64)";
|
||||||
m_displayField.append(field2);
|
m_displayField.append(field2);
|
||||||
|
|
||||||
FieldInfo field3;
|
FieldInfo field3;
|
||||||
field3.originalName = "data_type_id";
|
field3.originalName = "data_type_id";
|
||||||
field3.displayName = QString::fromWCharArray(L"数据类型");
|
field3.displayName = QString::fromWCharArray(L"数据类型");
|
||||||
|
field3.dataType = "bigint";
|
||||||
m_displayField.append(field3);
|
m_displayField.append(field3);
|
||||||
|
|
||||||
FieldInfo field4;
|
FieldInfo field4;
|
||||||
field4.originalName = "length_precision";
|
field4.originalName = "length_precision";
|
||||||
field4.displayName = QString::fromWCharArray(L"数据精度");
|
field4.displayName = QString::fromWCharArray(L"数据精度");
|
||||||
|
field4.dataType = "integer";
|
||||||
m_displayField.append(field4);
|
m_displayField.append(field4);
|
||||||
|
|
||||||
FieldInfo field5;
|
FieldInfo field5;
|
||||||
field5.originalName = "default_value";
|
field5.originalName = "default_value";
|
||||||
field5.displayName = QString::fromWCharArray(L"默认值");
|
field5.displayName = QString::fromWCharArray(L"默认值");
|
||||||
|
field5.dataType = "character varying(64)";
|
||||||
m_displayField.append(field5);
|
m_displayField.append(field5);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
#include "attributeView.h"
|
#include "attributeView.h"
|
||||||
#include "attributeTableDelegate.h"
|
#include "attributeTableDelegate.h"
|
||||||
|
#include "multiLineHeaderView.h"
|
||||||
#include <QHeaderView>
|
#include <QHeaderView>
|
||||||
#include <QVBoxLayout>
|
#include <QVBoxLayout>
|
||||||
|
#include <QTimer>
|
||||||
|
|
||||||
AttributeView::AttributeView(const ModelAttributeGroup& modelAttributeGroup, QWidget* parent, const QString& connection, const QString& tableName)
|
AttributeView::AttributeView(const ModelAttributeGroup& modelAttributeGroup, QWidget* parent, const QString& connection, const QString& tableName)
|
||||||
: QWidget(parent)
|
: QWidget(parent)
|
||||||
|
|
@ -11,7 +13,7 @@ AttributeView::AttributeView(const ModelAttributeGroup& modelAttributeGroup, QWi
|
||||||
{
|
{
|
||||||
m_tableView = new QTableView(this);
|
m_tableView = new QTableView(this);
|
||||||
m_tableView->verticalHeader()->setVisible(false);
|
m_tableView->verticalHeader()->setVisible(false);
|
||||||
m_tableView->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft | Qt::AlignVCenter);
|
//m_tableView->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft | Qt::AlignVCenter);
|
||||||
|
|
||||||
m_attributeTableModel = new AttributeTableModel(m_modelAttributeGroup, this, m_connection, m_attributeTable);
|
m_attributeTableModel = new AttributeTableModel(m_modelAttributeGroup, this, m_connection, m_attributeTable);
|
||||||
m_tableView->setModel(m_attributeTableModel);
|
m_tableView->setModel(m_attributeTableModel);
|
||||||
|
|
@ -19,6 +21,29 @@ AttributeView::AttributeView(const ModelAttributeGroup& modelAttributeGroup, QWi
|
||||||
AttributeTableDelegate* delegate = new AttributeTableDelegate(m_tableView, m_tableView);
|
AttributeTableDelegate* delegate = new AttributeTableDelegate(m_tableView, m_tableView);
|
||||||
m_tableView->setItemDelegate(delegate);
|
m_tableView->setItemDelegate(delegate);
|
||||||
|
|
||||||
|
//自定义表头
|
||||||
|
m_multiLinHeader = new MultiLineHeaderView(Qt::Horizontal, this);
|
||||||
|
QColor bg(246, 246, 246);
|
||||||
|
QColor border(228, 228, 228);
|
||||||
|
m_multiLinHeader->setBackgroundColor(bg);
|
||||||
|
m_multiLinHeader->setBorderColor(border);
|
||||||
|
//主标题加粗展示
|
||||||
|
for(int i =0; i < m_attributeTableModel->columnCount(); i++)
|
||||||
|
{
|
||||||
|
HeaderLineStyle mainTitleStyle;
|
||||||
|
mainTitleStyle.font.setBold(true);
|
||||||
|
m_multiLinHeader->setSectionLineStyle(i, 0, mainTitleStyle);
|
||||||
|
HeaderLineStyle subTitleStyle;
|
||||||
|
//subTitleStyle.font.setPointSize(8);
|
||||||
|
m_multiLinHeader->setSectionLineStyle(i, 1, subTitleStyle);
|
||||||
|
}
|
||||||
|
m_tableView->setHorizontalHeader(m_multiLinHeader);
|
||||||
|
//除了第一列其余列恢复可以手动调整模式
|
||||||
|
QTimer::singleShot(1000, [=](){
|
||||||
|
for(int i = 1; i < m_multiLinHeader->count(); i++)
|
||||||
|
m_multiLinHeader->setSectionResizeMode(i, QHeaderView::Interactive);
|
||||||
|
});
|
||||||
|
|
||||||
m_vLayout = new QVBoxLayout(this);
|
m_vLayout = new QVBoxLayout(this);
|
||||||
m_vLayout->setSpacing(0);
|
m_vLayout->setSpacing(0);
|
||||||
m_vLayout->setContentsMargins(0, 0, 0, 0);
|
m_vLayout->setContentsMargins(0, 0, 0, 0);
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
qputenv("QT_WAYLAND_DISABLE_WINDOWDECORATION", "0"); // Wayland 下启用装饰
|
||||||
QApplication a(argc, argv);
|
QApplication a(argc, argv);
|
||||||
LOG_INFO("Application", "------------------------------------------------Application start------------------------------------------------");
|
LOG_INFO("Application", "------------------------------------------------Application start------------------------------------------------");
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -99,8 +99,12 @@ void MainWindow::showMessageDialog(MessageDialogType type,const QString& strTitl
|
||||||
}
|
}
|
||||||
|
|
||||||
m_pMessageDialog->setMessage(type, strTitle, strContent);
|
m_pMessageDialog->setMessage(type, strTitle, strContent);
|
||||||
int nX = this->geometry().x() + (this->width() - m_pMessageDialog->width()) * 0.5;
|
// int nX = this->geometry().x() + (this->width() - m_pMessageDialog->width()) * 0.5;
|
||||||
int nY = this->geometry().y() + (this->height() - m_pMessageDialog->height()) * 0.5;
|
// int nY = this->geometry().y() + (this->height() - m_pMessageDialog->height()) * 0.5;
|
||||||
|
// m_pMessageDialog->move(nX, nY);
|
||||||
|
QRect parentFrame = this->frameGeometry(); // 获取父窗口的完整几何信息(包含边框和标题栏),适用于快平台对其
|
||||||
|
int nX = parentFrame.x() + (parentFrame.width() - m_pMessageDialog->width()) / 2;
|
||||||
|
int nY = parentFrame.y() + (parentFrame.height() - m_pMessageDialog->height()) / 2;
|
||||||
m_pMessageDialog->move(nX, nY);
|
m_pMessageDialog->move(nX, nY);
|
||||||
//m_pMessageDialog->raise();
|
//m_pMessageDialog->raise();
|
||||||
// if(type == type_question)
|
// if(type == type_question)
|
||||||
|
|
@ -142,8 +146,12 @@ void MainWindow::onActionTrigger_connect()
|
||||||
connect(m_pConnectionDialog, &ConnectionDialog::addConnection, this, &MainWindow::onSIG_addConnection);
|
connect(m_pConnectionDialog, &ConnectionDialog::addConnection, this, &MainWindow::onSIG_addConnection);
|
||||||
}
|
}
|
||||||
|
|
||||||
int nX = this->geometry().x() + (this->width() - m_pConnectionDialog->width()) * 0.5;
|
/* int nX = this->geometry().x() + (this->width() - m_pConnectionDialog->width()) * 0.5;
|
||||||
int nY = this->geometry().y() + (this->height() - m_pConnectionDialog->height()) * 0.5;
|
int nY = this->geometry().y() + (this->height() - m_pConnectionDialog->height()) * 0.5;
|
||||||
|
m_pConnectionDialog->move(nX, nY);*/
|
||||||
|
QRect parentFrame = this->frameGeometry(); // 获取父窗口的完整几何信息(包含边框和标题栏),适用于快平台对其
|
||||||
|
int nX = parentFrame.x() + (parentFrame.width() - m_pConnectionDialog->width()) / 2;
|
||||||
|
int nY = parentFrame.y() + (parentFrame.height() - m_pConnectionDialog->height()) / 2;
|
||||||
m_pConnectionDialog->move(nX, nY);
|
m_pConnectionDialog->move(nX, nY);
|
||||||
m_pConnectionDialog->exec();
|
m_pConnectionDialog->exec();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,104 @@
|
||||||
|
#include "multiLineHeaderView.h"
|
||||||
|
#include <QPainter>
|
||||||
|
|
||||||
|
MultiLineHeaderView::MultiLineHeaderView(Qt::Orientation orientation, QWidget* parent)
|
||||||
|
: QHeaderView(orientation, parent)
|
||||||
|
{
|
||||||
|
m_linSpacing = 2;
|
||||||
|
m_bgColor = QColor(Qt::white);
|
||||||
|
m_borderColor = QColor(Qt::lightGray);
|
||||||
|
setSectionResizeMode(QHeaderView::ResizeToContents);//根据内容自动调整大小
|
||||||
|
}
|
||||||
|
|
||||||
|
void MultiLineHeaderView::setLineSpacing(int spacing)
|
||||||
|
{
|
||||||
|
m_linSpacing = spacing;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MultiLineHeaderView::setBackgroundColor(QColor& color)
|
||||||
|
{
|
||||||
|
m_bgColor = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MultiLineHeaderView::setBorderColor(QColor& color)
|
||||||
|
{
|
||||||
|
m_borderColor = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MultiLineHeaderView::paintSection(QPainter* painter, const QRect& rect, int logicalIndex) const
|
||||||
|
{
|
||||||
|
if(!painter->isActive())
|
||||||
|
return;
|
||||||
|
|
||||||
|
//绘制背景
|
||||||
|
painter->fillRect(rect, m_bgColor);
|
||||||
|
//获取文本
|
||||||
|
QString text = model()->headerData(logicalIndex, orientation()).toString();
|
||||||
|
QStringList lines = text.split('\n');
|
||||||
|
//获取当前列的样式
|
||||||
|
QMap<int, HeaderLineStyle> styles = m_sectionStyles.value(logicalIndex);
|
||||||
|
//计算总高度并垂直居中
|
||||||
|
int totalHeight = 0;
|
||||||
|
QVector<int> lineHeights;
|
||||||
|
for(int i = 0; i < lines.size(); i++)
|
||||||
|
{
|
||||||
|
HeaderLineStyle style = styles.value(i, m_defaultStyle);
|
||||||
|
QFontMetrics fm(style.font);
|
||||||
|
lineHeights.append(fm.height());
|
||||||
|
totalHeight += fm.height() + (i < lines.size() - 1 ? m_linSpacing : 0);
|
||||||
|
}
|
||||||
|
int y = rect.y() + (rect.height() - totalHeight) * 0.5;
|
||||||
|
//逐行绘制文本
|
||||||
|
for(int i = 0; i < lines.size(); i++)
|
||||||
|
{
|
||||||
|
const QString& line = lines.at(i);
|
||||||
|
HeaderLineStyle style = styles.value(i, m_defaultStyle);
|
||||||
|
QFontMetrics fm(style.font);
|
||||||
|
//水平位置
|
||||||
|
int padding = 10;
|
||||||
|
int x = rect.x() + padding; //左对齐
|
||||||
|
if(style.alignment & Qt::AlignRight) //右对齐
|
||||||
|
x = rect.right() - fm.horizontalAdvance(line) - 4;//'horizontalAdvance'计算文本的横向距离
|
||||||
|
else if(style.alignment & Qt::AlignHCenter) //水平居中
|
||||||
|
x = rect.x() + (rect.width() - fm.horizontalAdvance(line)) * 0.5;
|
||||||
|
//设置字体和颜色
|
||||||
|
painter->setFont(style.font);
|
||||||
|
painter->setPen(style.color);
|
||||||
|
//绘制文本
|
||||||
|
painter->drawText(x, y + fm.ascent(), line); //绘制文本的基线X轴离文本上方的距离为ascent,下方距离为descent
|
||||||
|
y = y + lineHeights[i] + m_linSpacing;
|
||||||
|
}
|
||||||
|
|
||||||
|
//绘制边框
|
||||||
|
QPen pen(m_borderColor, 1);
|
||||||
|
painter->setPen(pen);
|
||||||
|
QRect adjustRect = rect.adjusted(0, 0, 1, 0);
|
||||||
|
painter->drawLine(adjustRect.topLeft(), adjustRect.bottomLeft());
|
||||||
|
painter->drawLine(adjustRect.topRight(), adjustRect.bottomRight());
|
||||||
|
}
|
||||||
|
//自动调整行高
|
||||||
|
QSize MultiLineHeaderView::sectionSizeFromContents(int logicalIndex) const
|
||||||
|
{
|
||||||
|
//获取文本
|
||||||
|
QString text = model()->headerData(logicalIndex, orientation()).toString();
|
||||||
|
//获取当前列的样式
|
||||||
|
QMap<int, HeaderLineStyle> styles = m_sectionStyles.value(logicalIndex);
|
||||||
|
QStringList lines = text.split('\n');
|
||||||
|
int maxWidth = 0;
|
||||||
|
int totalHeight = 0;
|
||||||
|
for(int i = 0; i < lines.size(); i++)
|
||||||
|
{
|
||||||
|
HeaderLineStyle style = styles.value(i, m_defaultStyle);
|
||||||
|
QFontMetrics fm(style.font);
|
||||||
|
maxWidth = qMax(maxWidth, fm.horizontalAdvance(lines[i]));
|
||||||
|
totalHeight += fm.height() + (i < lines.size() - 1 ? m_linSpacing : 0);
|
||||||
|
}
|
||||||
|
//qDebug() << maxWidth << "," << totalHeight;
|
||||||
|
return QSize(maxWidth + 20, totalHeight + 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MultiLineHeaderView::setSectionLineStyle(int section, int line, const HeaderLineStyle& style)
|
||||||
|
{
|
||||||
|
m_sectionStyles[section][line] = style;
|
||||||
|
updateSection(section);
|
||||||
|
}
|
||||||
|
|
@ -68,12 +68,10 @@ QTabBar::tab:selected
|
||||||
|
|
||||||
QHeaderView
|
QHeaderView
|
||||||
{
|
{
|
||||||
background-color: rgb(240, 240, 240);
|
background-color: rgb(250, 250, 250);
|
||||||
}
|
}
|
||||||
QHeaderView::section
|
QHeaderView::section
|
||||||
{
|
{
|
||||||
height:26px;
|
|
||||||
background-color: transparent;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QTableView
|
QTableView
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue