添加自定义HeaderView,支持多行展示,支持每一行的样式设置,支持section大小随内自适配
This commit is contained in:
parent
8cb6fdd5ae
commit
90e0599dd9
|
|
@ -30,6 +30,7 @@ set(H_HEADER_FILES
|
|||
include/settings.h
|
||||
include/tableWidgetHoverDelegate.h
|
||||
include/customMenu.h
|
||||
include/multiLineHeaderView.h
|
||||
include/modelInfoEditDialog.h
|
||||
include/sqlQueryExecutor.h
|
||||
include/attributeTableModel.h
|
||||
|
|
@ -52,6 +53,7 @@ set(CPP_SOURCE_FILES
|
|||
source/settings.cpp
|
||||
source/tableWidgetHoverDelegate.cpp
|
||||
source/customMenu.cpp
|
||||
source/multiLineHeaderView.cpp
|
||||
source/modelInfoEditDialog.cpp
|
||||
source/sqlQueryExecutor.cpp
|
||||
source/attributeTableModel.cpp
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
#include "attributeTableModel.h"
|
||||
|
||||
class QVBoxLayout;
|
||||
class MultiLineHeaderView;
|
||||
class AttributeView : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
|
|
@ -31,6 +32,8 @@ private:
|
|||
QTableView* m_tableView;
|
||||
AttributeTableModel* m_attributeTableModel;
|
||||
QVBoxLayout* m_vLayout;
|
||||
|
||||
MultiLineHeaderView* m_multiLinHeader;
|
||||
};
|
||||
|
||||
#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();
|
||||
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);
|
||||
|
|
@ -144,7 +148,7 @@ Qt::ItemFlags AttributeTableModel::flags(const QModelIndex &index) const
|
|||
QString text = numberIndex.data(Qt::DisplayRole).toString();
|
||||
|
||||
Qt::ItemFlags flags = QAbstractTableModel::flags(index);
|
||||
if (index.column() != 0 || !text.contains("-")) //行号列不能编辑
|
||||
if (index.column() != 0 && !text.contains("-")) //行号列和处于删除状态的item不能编辑
|
||||
flags = flags | Qt::ItemIsEditable;
|
||||
return flags;
|
||||
}
|
||||
|
|
@ -154,26 +158,31 @@ void AttributeTableModel::iniDisplayField()
|
|||
FieldInfo field1;
|
||||
field1.originalName = "attribute";
|
||||
field1.displayName = QString::fromWCharArray(L"属性类别");
|
||||
field1.dataType = "character varying(128)";
|
||||
m_displayField.append(field1);
|
||||
|
||||
FieldInfo field2;
|
||||
field2.originalName = "attribute_name";
|
||||
field2.displayName = QString::fromWCharArray(L"属性名称");
|
||||
field2.dataType = "character varying(64)";
|
||||
m_displayField.append(field2);
|
||||
|
||||
FieldInfo field3;
|
||||
field3.originalName = "data_type_id";
|
||||
field3.displayName = QString::fromWCharArray(L"数据类型");
|
||||
field3.dataType = "bigint";
|
||||
m_displayField.append(field3);
|
||||
|
||||
FieldInfo field4;
|
||||
field4.originalName = "length_precision";
|
||||
field4.displayName = QString::fromWCharArray(L"数据精度");
|
||||
field4.dataType = "integer";
|
||||
m_displayField.append(field4);
|
||||
|
||||
FieldInfo field5;
|
||||
field5.originalName = "default_value";
|
||||
field5.displayName = QString::fromWCharArray(L"默认值");
|
||||
field5.dataType = "character varying(64)";
|
||||
m_displayField.append(field5);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
#include "attributeView.h"
|
||||
#include "attributeTableDelegate.h"
|
||||
#include "multiLineHeaderView.h"
|
||||
#include <QHeaderView>
|
||||
#include <QVBoxLayout>
|
||||
#include <QTimer>
|
||||
|
||||
AttributeView::AttributeView(const ModelAttributeGroup& modelAttributeGroup, QWidget* parent, const QString& connection, const QString& tableName)
|
||||
: QWidget(parent)
|
||||
|
|
@ -11,7 +13,7 @@ AttributeView::AttributeView(const ModelAttributeGroup& modelAttributeGroup, QWi
|
|||
{
|
||||
m_tableView = new QTableView(this);
|
||||
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_tableView->setModel(m_attributeTableModel);
|
||||
|
|
@ -19,6 +21,29 @@ AttributeView::AttributeView(const ModelAttributeGroup& modelAttributeGroup, QWi
|
|||
AttributeTableDelegate* delegate = new AttributeTableDelegate(m_tableView, m_tableView);
|
||||
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->setSpacing(0);
|
||||
m_vLayout->setContentsMargins(0, 0, 0, 0);
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
qputenv("QT_WAYLAND_DISABLE_WINDOWDECORATION", "0"); // Wayland 下启用装饰
|
||||
QApplication a(argc, argv);
|
||||
LOG_INFO("Application", "------------------------------------------------Application start------------------------------------------------");
|
||||
|
||||
|
|
|
|||
|
|
@ -99,8 +99,12 @@ void MainWindow::showMessageDialog(MessageDialogType type,const QString& strTitl
|
|||
}
|
||||
|
||||
m_pMessageDialog->setMessage(type, strTitle, strContent);
|
||||
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 nX = this->geometry().x() + (this->width() - m_pMessageDialog->width()) * 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->raise();
|
||||
// if(type == type_question)
|
||||
|
|
@ -142,8 +146,12 @@ void MainWindow::onActionTrigger_connect()
|
|||
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;
|
||||
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->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
|
||||
{
|
||||
background-color: rgb(240, 240, 240);
|
||||
background-color: rgb(250, 250, 250);
|
||||
}
|
||||
QHeaderView::section
|
||||
{
|
||||
height:26px;
|
||||
background-color: transparent;
|
||||
}
|
||||
|
||||
QTableView
|
||||
|
|
|
|||
Loading…
Reference in New Issue