【Qt C++自绘制界面音乐播放器-5】添加左侧控制栏和Logo

40 阅读3分钟

最新大型开源项目-云游戏,云桌面系统,欢迎关注

GammaRay源码地址

本项目代码地址

源码

1.实现左侧控制栏

软件界面对应的位置为橙色边框区域,这个区域比较简单,可以分为2个部分:

1.圆形logo部分

2.四个按钮组成的功能区域

1.1 首先,去掉标题栏的背景色

在TitleBar的paintEvent方法中,注释掉绘制代码

void TitleBar::paintEvent(QPaintEvent *event) {
#if 0
    QPainter painter(this);
    painter.setBrush(QBrush(0x0099ff));
    painter.drawRect(this->rect());
#endif
}

得到如下干净的页面效果:

2.实现Logo区域

2.1 实现Logo区域,新建一个Avatar类,继承自QWidget,实现paintEvent方法

我们绘制一个1像素的圆圈,圆圈内绘制一个Logo图片。

使用drawPixmap绘制,因此需要一个QPixmap变量存储图片

class Avatar : public QWidget
{
    Q_OBJECT
public:
   // 指定当前Widget的大小,图片也将使用这个尺寸进行缩放
    explicit Avatar(int size, QWidget *parent = nullptr);

    void paintEvent(QPaintEvent *event) override;

private:
    // 保存要绘制的图片
    QPixmap pixmap_;

};
Avatar::Avatar(int size, QWidget *parent) : QWidget(parent) {
    //设置Widget的大小
    setFixedSize(QSize(size, size));
    // 加载图片
    QImage image;
    image.load(":/images/resources/avatar.png");
    pixmap_ = QPixmap::fromImage(image);
    // 按照尺寸将图片进行缩放
    // Qt::KeepAspectRatio 参数代表保持图片的比例
    // Qt::SmoothTransformation 参数代表平滑缩放,相对Fast模式慢一点,但效果更好
    pixmap_ = pixmap_.scaled(Settings::kAvatarSize, Settings::kAvatarSize, Qt::KeepAspectRatio, Qt::SmoothTransformation);
}

void Avatar::paintEvent(QPaintEvent *event) {
    QPainter painter(this);
    // 开启抗锯齿,绘制效果更平滑
    painter.setRenderHint(QPainter::RenderHint::Antialiasing);
    // 设置画笔,用来绘制圆圈
    QPen pen;
    pen.setColor(0x334466);
    pen.setWidth(1);
    painter.setPen(pen);
    // 这里使用绘制椭圆来绘制一个圆,还记得吗,前面使用的是绘制圆角矩形的方式进行绘制的。
    // 这里的参数1,意思是向内偏移一个像素,那么左右2边共便宜2个像素,上下也是同样的道理。
    painter.drawEllipse(QRect(1, 1, this->rect().width()-2, this->rect().height()-2));

    // 绘制图片
    if (!pixmap_.isNull()) {
        painter.drawPixmap(0, 0, pixmap_);
    }
}

为什么绘制圆圈时,要向内便宜一个像素呢?请看下图:

如果不往内部偏移,圆圈的线,宽度一版会在绘制区域之外。

2.2 如何添加图片

在上面的代码中,图片是这样加载的。像字体,图片等所有资源都是这样的规则,一定要记住。

QImage image;
image.load(":/images/resources/avatar.png")

3.创建一个类管理和布局

3.1 新建一个SideBar类,用于管理Logo和四个按钮
class SideBar : public QWidget
{
    Q_OBJECT
public:
    explicit SideBar(QWidget *parent = nullptr);
    void paintEvent(QPaintEvent *event) override;
};
SideBar::SideBar(QWidget *parent) : QWidget(parent) {
    this->setFixedSize(QSize(Settings::kSideBarWidth, 530));
}

void SideBar::paintEvent(QPaintEvent *event) {
#if 1
    QPainter painter(this);
    painter.setBrush(QBrush(0x009988));
    painter.drawRect(this->rect());
#endif
}
3.2 添加到MainWindow中去
MainWindow::MainWindow(QWidget *parent)
    : QWidget(parent) {
...
    title_bar_ = new TitleBar(this);
    side_bar_ = new SideBar(this);

...
    root_layout->addWidget(title_bar_);

    // 左边控制栏和右面的内容区域,都放在这个横向的布局里
    auto content_layout = new QHBoxLayout();
    // 这里是清除边距
    content_layout->setSpacing(0);
    content_layout->setMargin(0);
    // 左面偏移5个像素,这是因为做阴影用掉了5个像素,还记得吗
    content_layout->addSpacing(5);
    // !!! 将我们的控制栏添加在这里 !!!
    content_layout->addWidget(side_bar_);
    content_layout->addStretch();

    root_layout->addLayout(content_layout);
    content_layout->addSpacing(5);

    root_layout->addStretch();
    setLayout(root_layout);
}

我们将会得到这样的一个效果:

3.3 将Avatar添加到控制栏里,修改SideBar的构造函数,添加Avatar控件,同时取消掉绿色的背景。
SideBar::SideBar(QWidget *parent) : QWidget(parent) {
    this->setFixedSize(QSize(Settings::kSideBarWidth, 530));

    auto item_layout = new QVBoxLayout();
    LayoutHelper::ClearMarginSpacing(item_layout);
    // 这里将我们的Avatar添加进来,放在布局中
    // 这里使用了一对花括号,将Avatar相关的逻辑都放在里面了,方便管理。
    // 尤其时相同内容较多的时候,比较容易辨认。
    {
        // 创建Avatar
        auto avatar = new Avatar(Settings::kAvatarSize, this);
        // 创建一个横向的布局,目的是利用弹簧挤压,让Avatar水平居中
        auto avatar_layout = new QHBoxLayout();
        LayoutHelper::ClearMarginSpacing(avatar_layout);
        avatar_layout->addStretch();
        avatar_layout->addWidget(avatar);
        avatar_layout->addStretch();
        item_layout->addSpacing(30);
        item_layout->addLayout(avatar_layout);
    }
    item_layout->addStretch();
    setLayout(item_layout);
}

再次执行后,得到的画面是这样的,就达到目的了: