fix(ui): 修复改名导致的停靠布局丢失(bump dockState键丢弃失配旧布局) + 用户区改回QToolButton(头像图标+姓名职务一行,整块可点)修复挤成一团
This commit is contained in:
parent
c953b35334
commit
3ccb8df4ed
|
|
@ -3,12 +3,15 @@
|
||||||
#include <QAbstractButton>
|
#include <QAbstractButton>
|
||||||
#include <QActionGroup>
|
#include <QActionGroup>
|
||||||
#include <QColor>
|
#include <QColor>
|
||||||
|
#include <QFont>
|
||||||
#include <QFrame>
|
#include <QFrame>
|
||||||
#include <QHBoxLayout>
|
#include <QHBoxLayout>
|
||||||
|
#include <QIcon>
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
#include <QMenu>
|
#include <QMenu>
|
||||||
#include <QMenuBar>
|
#include <QMenuBar>
|
||||||
#include <QPushButton>
|
#include <QPainter>
|
||||||
|
#include <QPixmap>
|
||||||
#include <QSize>
|
#include <QSize>
|
||||||
#include <QStringList>
|
#include <QStringList>
|
||||||
#include <QToolButton>
|
#include <QToolButton>
|
||||||
|
|
@ -50,6 +53,29 @@ QWidget* makeIconButton(QWidget* parent, Glyph icon, const QString& tip)
|
||||||
return btn;
|
return btn;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 圆形头像图标:强调色填充 + 白色缩写。2x 绘制保证高 DPI 清晰。
|
||||||
|
QPixmap renderAvatar(const QString& initials, int px, const QColor& bg, const QColor& fg)
|
||||||
|
{
|
||||||
|
constexpr int kScale = 2;
|
||||||
|
const int s = px * kScale;
|
||||||
|
QPixmap pm(s, s);
|
||||||
|
pm.fill(Qt::transparent);
|
||||||
|
QPainter p(&pm);
|
||||||
|
p.setRenderHint(QPainter::Antialiasing, true);
|
||||||
|
p.setPen(Qt::NoPen);
|
||||||
|
p.setBrush(bg);
|
||||||
|
p.drawEllipse(0, 0, s, s);
|
||||||
|
QFont f = p.font();
|
||||||
|
f.setPixelSize(static_cast<int>(s * 0.4));
|
||||||
|
f.setBold(true);
|
||||||
|
p.setFont(f);
|
||||||
|
p.setPen(fg);
|
||||||
|
p.drawText(QRect(0, 0, s, s), Qt::AlignCenter, initials);
|
||||||
|
p.end();
|
||||||
|
pm.setDevicePixelRatio(kScale);
|
||||||
|
return pm;
|
||||||
|
}
|
||||||
|
|
||||||
// ── 四个菜单(结构对齐需求;叶子项当前为静态占位,后续接真实页面)──
|
// ── 四个菜单(结构对齐需求;叶子项当前为静态占位,后续接真实页面)──
|
||||||
QMenu* buildViewMenu(QWidget* p)
|
QMenu* buildViewMenu(QWidget* p)
|
||||||
{
|
{
|
||||||
|
|
@ -146,7 +172,8 @@ TopBar::TopBar(QWidget* parent) : QWidget(parent) {
|
||||||
" subcontrol-position: right center; subcontrol-origin: padding; right:8px; }"
|
" subcontrol-position: right center; subcontrol-origin: padding; right:8px; }"
|
||||||
"QToolButton#iconBtn { border:none; border-radius:8px; padding:8px; }"
|
"QToolButton#iconBtn { border:none; border-radius:8px; padding:8px; }"
|
||||||
"QToolButton#iconBtn:hover { background:{{bg/hover}}; }"
|
"QToolButton#iconBtn:hover { background:{{bg/hover}}; }"
|
||||||
"#userBtn { border:none; border-radius:8px; padding:2px 4px; text-align:left; }"
|
"#userBtn { border:none; border-radius:8px; padding:4px 10px 4px 6px;"
|
||||||
|
" color:{{text/primary}}; font-size:%3px; }"
|
||||||
"#userBtn:hover { background:{{bg/hover}}; }"
|
"#userBtn:hover { background:{{bg/hover}}; }"
|
||||||
"#userBtn::menu-indicator { image:none; }"
|
"#userBtn::menu-indicator { image:none; }"
|
||||||
"#avatar { background:{{accent/primary}}; color:{{text/on-primary}}; border-radius:17px; font-weight:%2;"
|
"#avatar { background:{{accent/primary}}; color:{{text/on-primary}}; border-radius:17px; font-weight:%2;"
|
||||||
|
|
@ -205,37 +232,21 @@ TopBar::TopBar(QWidget* parent) : QWidget(parent) {
|
||||||
lay->addWidget(makeDivider(this));
|
lay->addWidget(makeDivider(this));
|
||||||
lay->addSpacing(12);
|
lay->addSpacing(12);
|
||||||
|
|
||||||
// 用户区:头像 + 姓名 + 职务 同一行,整块可点击(QPushButton + 子布局,子控件鼠标穿透→点击命中按钮)。
|
// 用户区:头像(圆形图标) + 姓名·职务 同一行,整块可点击 → 退出登录菜单。
|
||||||
auto* userBtn = new QPushButton(this);
|
// 用 QToolButton(图标+文字),而非 QPushButton+子布局——后者按空文本算尺寸会把内容挤成一团。
|
||||||
|
auto* userBtn = new QToolButton(this);
|
||||||
userBtn->setObjectName(QStringLiteral("userBtn"));
|
userBtn->setObjectName(QStringLiteral("userBtn"));
|
||||||
|
userBtn->setIcon(QIcon(renderAvatar(QStringLiteral("ZL"), 30,
|
||||||
|
geopro::app::tokenColor("accent/primary"), Qt::white)));
|
||||||
|
userBtn->setIconSize(QSize(30, 30));
|
||||||
|
userBtn->setText(QStringLiteral("张磊 · 高级工程师"));
|
||||||
|
userBtn->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
|
||||||
|
userBtn->setPopupMode(QToolButton::InstantPopup);
|
||||||
userBtn->setCursor(Qt::PointingHandCursor);
|
userBtn->setCursor(Qt::PointingHandCursor);
|
||||||
userBtn->setFlat(true);
|
|
||||||
auto* userLay = new QHBoxLayout(userBtn);
|
|
||||||
userLay->setContentsMargins(6, 2, 10, 2);
|
|
||||||
userLay->setSpacing(8);
|
|
||||||
|
|
||||||
auto* avatar = new QLabel(QStringLiteral("ZL"), userBtn);
|
|
||||||
avatar->setObjectName(QStringLiteral("avatar"));
|
|
||||||
avatar->setFixedSize(34, 34);
|
|
||||||
avatar->setAlignment(Qt::AlignCenter);
|
|
||||||
avatar->setAttribute(Qt::WA_TransparentForMouseEvents);
|
|
||||||
userLay->addWidget(avatar);
|
|
||||||
|
|
||||||
auto* userName = new QLabel(QStringLiteral("张磊"), userBtn);
|
|
||||||
userName->setObjectName(QStringLiteral("userName"));
|
|
||||||
userName->setAttribute(Qt::WA_TransparentForMouseEvents);
|
|
||||||
userLay->addWidget(userName);
|
|
||||||
|
|
||||||
auto* userRole = new QLabel(QStringLiteral("高级工程师"), userBtn);
|
|
||||||
userRole->setObjectName(QStringLiteral("userRole"));
|
|
||||||
userRole->setAttribute(Qt::WA_TransparentForMouseEvents);
|
|
||||||
userLay->addWidget(userRole);
|
|
||||||
|
|
||||||
auto* userMenu = new QMenu(userBtn);
|
auto* userMenu = new QMenu(userBtn);
|
||||||
QObject::connect(userMenu->addAction(QStringLiteral("退出登录")), &QAction::triggered, this,
|
QObject::connect(userMenu->addAction(QStringLiteral("退出登录")), &QAction::triggered, this,
|
||||||
[this] { emit logoutRequested(); });
|
[this] { emit logoutRequested(); });
|
||||||
userBtn->setMenu(userMenu);
|
userBtn->setMenu(userMenu);
|
||||||
|
|
||||||
lay->addWidget(userBtn);
|
lay->addWidget(userBtn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -999,7 +999,9 @@ void buildWorkbench(QMainWindow& window, geopro::data::LocalSampleRepository& re
|
||||||
const QSettings settings;
|
const QSettings settings;
|
||||||
const QByteArray geo = settings.value(QStringLiteral("ui/geometry")).toByteArray();
|
const QByteArray geo = settings.value(QStringLiteral("ui/geometry")).toByteArray();
|
||||||
if (!geo.isEmpty()) window.restoreGeometry(geo);
|
if (!geo.isEmpty()) window.restoreGeometry(geo);
|
||||||
const QByteArray dockState = settings.value(QStringLiteral("ui/dockState")).toByteArray();
|
// 注意:ADS 按 dock 唯一名作键。改过 dock 名后旧布局会失配 → bump 此键丢弃旧布局,
|
||||||
|
// 回落到下方 addDockWidget 的默认排布(再改 dock 名时同样要 bump 版本号)。
|
||||||
|
const QByteArray dockState = settings.value(QStringLiteral("ui/dockState_v2")).toByteArray();
|
||||||
if (!dockState.isEmpty()) {
|
if (!dockState.isEmpty()) {
|
||||||
dockManager->restoreState(dockState);
|
dockManager->restoreState(dockState);
|
||||||
// restoreState 重建停靠区会重新显示 ADS 标题栏,再隐藏一次保持“无双标题”。
|
// restoreState 重建停靠区会重新显示 ADS 标题栏,再隐藏一次保持“无双标题”。
|
||||||
|
|
@ -1010,7 +1012,7 @@ void buildWorkbench(QMainWindow& window, geopro::data::LocalSampleRepository& re
|
||||||
QObject::connect(qApp, &QCoreApplication::aboutToQuit, dockManager, [dockManager, &window]() {
|
QObject::connect(qApp, &QCoreApplication::aboutToQuit, dockManager, [dockManager, &window]() {
|
||||||
QSettings settings;
|
QSettings settings;
|
||||||
settings.setValue(QStringLiteral("ui/geometry"), window.saveGeometry());
|
settings.setValue(QStringLiteral("ui/geometry"), window.saveGeometry());
|
||||||
settings.setValue(QStringLiteral("ui/dockState"), dockManager->saveState());
|
settings.setValue(QStringLiteral("ui/dockState_v2"), dockManager->saveState());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue