feat(topbar): 用户区按样图重做(头像竖直居中+姓名/职务两行左对齐+下拉箭头,整块可点) + 加宽下拉菜单(账户/个人资料/偏好设置/API密钥/退出登录)
This commit is contained in:
parent
3ccb8df4ed
commit
9680fefbe3
|
|
@ -3,6 +3,7 @@
|
|||
#include <QAbstractButton>
|
||||
#include <QActionGroup>
|
||||
#include <QColor>
|
||||
#include <QEvent>
|
||||
#include <QFont>
|
||||
#include <QFrame>
|
||||
#include <QHBoxLayout>
|
||||
|
|
@ -13,6 +14,7 @@
|
|||
#include <QPainter>
|
||||
#include <QPixmap>
|
||||
#include <QSize>
|
||||
#include <QVBoxLayout>
|
||||
#include <QStringList>
|
||||
#include <QToolButton>
|
||||
#include <QWidget>
|
||||
|
|
@ -232,22 +234,65 @@ TopBar::TopBar(QWidget* parent) : QWidget(parent) {
|
|||
lay->addWidget(makeDivider(this));
|
||||
lay->addSpacing(12);
|
||||
|
||||
// 用户区:头像(圆形图标) + 姓名·职务 同一行,整块可点击 → 退出登录菜单。
|
||||
// 用 QToolButton(图标+文字),而非 QPushButton+子布局——后者按空文本算尺寸会把内容挤成一团。
|
||||
auto* userBtn = new QToolButton(this);
|
||||
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);
|
||||
auto* userMenu = new QMenu(userBtn);
|
||||
QObject::connect(userMenu->addAction(QStringLiteral("退出登录")), &QAction::triggered, this,
|
||||
// 用户区:头像(圆形,竖直居中) + 右侧 姓名(上)/职务(下) 左对齐 + 下拉箭头;整块可点 → 菜单。
|
||||
// 用普通 QWidget + eventFilter:QWidget 按子布局正确撑开(QPushButton 装布局会按空文字算尺寸挤成一团)。
|
||||
userRow_ = new QWidget(this);
|
||||
userRow_->setObjectName(QStringLiteral("userBtn"));
|
||||
userRow_->setAttribute(Qt::WA_StyledBackground, true); // 令 QSS 背景(hover)在 QWidget 上生效
|
||||
userRow_->setCursor(Qt::PointingHandCursor);
|
||||
userRow_->installEventFilter(this);
|
||||
auto* uLay = new QHBoxLayout(userRow_);
|
||||
uLay->setContentsMargins(8, 3, 8, 3);
|
||||
uLay->setSpacing(10);
|
||||
|
||||
auto* avatar = new QLabel(userRow_);
|
||||
avatar->setPixmap(
|
||||
renderAvatar(QStringLiteral("ZL"), 34, geopro::app::tokenColor("accent/primary"), Qt::white));
|
||||
avatar->setFixedSize(34, 34);
|
||||
avatar->setAttribute(Qt::WA_TransparentForMouseEvents);
|
||||
uLay->addWidget(avatar, 0, Qt::AlignVCenter);
|
||||
|
||||
auto* nameBox = new QWidget(userRow_);
|
||||
nameBox->setAttribute(Qt::WA_TransparentForMouseEvents);
|
||||
auto* nameLay = new QVBoxLayout(nameBox);
|
||||
nameLay->setContentsMargins(0, 0, 0, 0);
|
||||
nameLay->setSpacing(0);
|
||||
auto* userName = new QLabel(QStringLiteral("张磊"), nameBox);
|
||||
userName->setObjectName(QStringLiteral("userName"));
|
||||
auto* userRole = new QLabel(QStringLiteral("高级工程师"), nameBox);
|
||||
userRole->setObjectName(QStringLiteral("userRole"));
|
||||
nameLay->addWidget(userName);
|
||||
nameLay->addWidget(userRole);
|
||||
uLay->addWidget(nameBox, 0, Qt::AlignVCenter);
|
||||
|
||||
auto* chevronLbl = new QLabel(userRow_);
|
||||
chevronLbl->setPixmap(QPixmap(geopro::app::writeChevronIcon(true, QColor("#7C8493")))
|
||||
.scaled(12, 12, Qt::KeepAspectRatio, Qt::SmoothTransformation));
|
||||
chevronLbl->setAttribute(Qt::WA_TransparentForMouseEvents);
|
||||
uLay->addWidget(chevronLbl, 0, Qt::AlignVCenter);
|
||||
|
||||
// 下拉菜单(加宽):账户 / 个人资料 / 偏好设置 / API 密钥 / 退出登录。
|
||||
userMenu_ = new QMenu(this);
|
||||
userMenu_->setMinimumWidth(200);
|
||||
userMenu_->addAction(QStringLiteral("账户"));
|
||||
userMenu_->addAction(QStringLiteral("个人资料"));
|
||||
QObject::connect(userMenu_->addAction(QStringLiteral("偏好设置")), &QAction::triggered, this,
|
||||
[this] { emit settingsRequested(); });
|
||||
userMenu_->addAction(QStringLiteral("API 密钥"));
|
||||
userMenu_->addSeparator();
|
||||
QObject::connect(userMenu_->addAction(QStringLiteral("退出登录")), &QAction::triggered, this,
|
||||
[this] { emit logoutRequested(); });
|
||||
userBtn->setMenu(userMenu);
|
||||
lay->addWidget(userBtn);
|
||||
|
||||
lay->addWidget(userRow_);
|
||||
}
|
||||
|
||||
bool TopBar::eventFilter(QObject* obj, QEvent* event) {
|
||||
if (obj == userRow_ && event->type() == QEvent::MouseButtonRelease) {
|
||||
if (userMenu_)
|
||||
userMenu_->exec(userRow_->mapToGlobal(QPoint(0, userRow_->height() + 2)));
|
||||
return true;
|
||||
}
|
||||
return QWidget::eventFilter(obj, event);
|
||||
}
|
||||
|
||||
void TopBar::setWorkspaces(const std::vector<data::Workspace>& list, const QString& currentId) {
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@
|
|||
#include "repo/RepoTypes.hpp"
|
||||
|
||||
class QToolButton;
|
||||
class QEvent;
|
||||
class QMenu;
|
||||
|
||||
namespace geopro::app {
|
||||
|
||||
|
|
@ -21,6 +23,9 @@ public:
|
|||
bool hasMore);
|
||||
void setProjectButtonText(const QString& name); // 弹窗切换项目后更新按钮文字
|
||||
|
||||
protected:
|
||||
bool eventFilter(QObject* obj, QEvent* event) override; // 用户区整块可点 → 弹菜单
|
||||
|
||||
signals:
|
||||
void workspaceSwitchRequested(const QString& tenantId);
|
||||
void projectSwitchRequested(const QString& projectId);
|
||||
|
|
@ -31,6 +36,8 @@ signals:
|
|||
private:
|
||||
QToolButton* wsBtn_ = nullptr;
|
||||
QToolButton* projBtn_ = nullptr;
|
||||
QWidget* userRow_ = nullptr; // 用户区整块(头像+姓名/职务+箭头)
|
||||
QMenu* userMenu_ = nullptr; // 用户下拉菜单
|
||||
};
|
||||
|
||||
} // namespace geopro::app
|
||||
|
|
|
|||
Loading…
Reference in New Issue