diff --git a/CMakeLists.txt b/CMakeLists.txt index a3b8df8..ebd12cc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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 diff --git a/include/attributeView.h b/include/attributeView.h index 29cac6b..0e826f7 100644 --- a/include/attributeView.h +++ b/include/attributeView.h @@ -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 diff --git a/include/multiLineHeaderView.h b/include/multiLineHeaderView.h new file mode 100644 index 0000000..4d41e90 --- /dev/null +++ b/include/multiLineHeaderView.h @@ -0,0 +1,37 @@ +#ifndef MULTILINEHEADERVIEW +#define MULTILINEHEADERVIEW + +#include + +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> m_sectionStyles; //列号->(行号->样式) + HeaderLineStyle m_defaultStyle; + QColor m_bgColor; //背景颜色 + QColor m_borderColor; //边框颜色 + int m_linSpacing; //行间距 +}; + +#endif //MULTILINEHEADERVIEW diff --git a/source/attributeTableModel.cpp b/source/attributeTableModel.cpp index 0a53a95..d2ad424 100644 --- a/source/attributeTableModel.cpp +++ b/source/attributeTableModel.cpp @@ -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); } diff --git a/source/attributeView.cpp b/source/attributeView.cpp index ad40dab..f47e770 100644 --- a/source/attributeView.cpp +++ b/source/attributeView.cpp @@ -1,7 +1,9 @@ #include "attributeView.h" #include "attributeTableDelegate.h" +#include "multiLineHeaderView.h" #include #include +#include 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); diff --git a/source/main.cpp b/source/main.cpp index 92d0866..7e01720 100644 --- a/source/main.cpp +++ b/source/main.cpp @@ -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------------------------------------------------"); diff --git a/source/mainwindow.cpp b/source/mainwindow.cpp index 7798c0f..2e99c5a 100644 --- a/source/mainwindow.cpp +++ b/source/mainwindow.cpp @@ -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(); } diff --git a/source/multiLineHeaderView.cpp b/source/multiLineHeaderView.cpp new file mode 100644 index 0000000..d7c7286 --- /dev/null +++ b/source/multiLineHeaderView.cpp @@ -0,0 +1,104 @@ +#include "multiLineHeaderView.h" +#include + +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 styles = m_sectionStyles.value(logicalIndex); + //计算总高度并垂直居中 + int totalHeight = 0; + QVector 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 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); +} diff --git a/ui/mainwindow.ui b/ui/mainwindow.ui index bf381db..ba5e633 100644 --- a/ui/mainwindow.ui +++ b/ui/mainwindow.ui @@ -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