c++ - 用 C++ 设计 Qt Creator 的侧边栏

标签 c++ qt qt5

我创建了一个类来制作侧边栏,就像在Qt Creator 中一样(左边一个)。我现在不知道如何让它看起来像 Qt creator 中的那个,因为我的看起来很丑!

sidebar.h:

#ifndef _SIDEBAR_H_
#define _SIDEBAR_H_

#include <QVector>
#include <QString>

#include <QWidget>
#include <QLabel>
#include <QVBoxLayout>
#include <QPixmap>

#include <iostream>

class SideBar : public QWidget
{
public:
    SideBar(QWidget *parent=nullptr);

    void addIcon(const char *name);
    void addIcon(QString &name);

private:
    QVBoxLayout *_layout;
};

#endif // SIDEBAR_H

侧边栏.cpp

#include "sidebar.h"

#include <QPushButton>
#include <QIcon>

SideBar::SideBar(QWidget *parent) : QWidget(parent)
{
    _layout = new QVBoxLayout(this);
    setLayout(_layout);
}

void SideBar::addIcon(const char *name)
{
    QString str(name);
    addIcon(str);
}

void SideBar::addIcon(QString &file)
{
    QPushButton *button = new QPushButton(this);

    QPixmap pixmap(file);
    QIcon buttonIcon(pixmap);

    button->setIcon(buttonIcon);
    // button->setIconSize(pixmap.rect().size());

    _layout->addWidget(button);
}

这是我想要的:

enter image description here

这是我得到的:

enter image description here

最佳答案

一个可能的解决方案是使用 QAction 来处理点击和图标,覆盖 paintEvent、mousePressEvent、mouseMoveEvent、leaveEvent 方法,更改有关小部件所处状态的颜色。

sidebar.h

#ifndef SIDEBAR_H
#define SIDEBAR_H

#include <QAction>
#include <QWidget>

class SideBar : public QWidget
{
    Q_OBJECT
public:
    explicit SideBar(QWidget *parent = nullptr);
    void addAction(QAction *action);
    QAction *addAction(const QString &text, const QIcon &icon = QIcon());
    QSize minimumSizeHint() const;

signals:

public slots:

protected:
    void paintEvent(QPaintEvent *event);
    void mousePressEvent(QMouseEvent *event);
    void mouseMoveEvent(QMouseEvent *event);
    void leaveEvent(QEvent * event);

    QAction *actionAt(const QPoint &at);
private:
    QList<QAction *> mActions;

    QAction *mCheckedAction;
    QAction *mOverAction;
};

#endif // SIDEBAR_H

sidebar.cpp

#include "sidebar.h"

#include <QPaintEvent>
#include <QPainter>
#include <QDebug>
#include <QEvent>

#define action_height 90


SideBar::SideBar(QWidget *parent) :
    QWidget(parent), mCheckedAction(NULL), mOverAction(NULL)
{
    setMouseTracking(true);
}


void SideBar::paintEvent(QPaintEvent *event)
{
    QPainter p(this);

    QFont fontText(p.font());
    fontText.setFamily("Helvetica Neue");
    p.setFont(fontText);

    int action_y = 0;
    p.fillRect(rect(), QColor(100, 100, 100));
    for(auto action: mActions)
    {

        QRect actionRect(0, action_y, event->rect().width(), action_height);

        if(action->isChecked())
        {
            p.fillRect(actionRect, QColor(35, 35, 35));
        }

        if(action == mOverAction){
            p.fillRect(actionRect, QColor(150, 150, 150));
        }

        p.setPen(QColor(255, 255, 255));
        QSize size = p.fontMetrics().size(Qt::TextSingleLine, action->text());
        QRect actionTextRect(QPoint(actionRect.width()/2 - size.width()/2, actionRect.bottom()-size.height()-5), size);
        p.drawText(actionTextRect, Qt::AlignCenter, action->text());

        QRect actionIconRect(0, action_y + 10, actionRect.width(), actionRect.height()-2*actionTextRect.height()-10);
        QIcon  actionIcon(action->icon());
        actionIcon.paint(&p, actionIconRect);

        action_y += actionRect.height();
    }

}

QSize SideBar::minimumSizeHint() const
{
    return action_height*QSize(1, mActions.size());
}

void SideBar::addAction(QAction *action)
{
    mActions.push_back(action);
    action->setCheckable(true);
    update();
}

QAction *SideBar::addAction(const QString &text, const QIcon &icon)
{
    QAction *action = new QAction(icon, text, this);
    action->setCheckable(true);
    mActions.push_back(action);
    update();
    return action;
}

void SideBar::mousePressEvent(QMouseEvent *event)
{
    QAction* tempAction = actionAt(event->pos());
    if(tempAction == NULL || tempAction->isChecked())
        return;
    qDebug()<<"clicked";
    if(mCheckedAction)
        mCheckedAction->setChecked(false);
    if(mOverAction == tempAction)
        mOverAction = NULL;
    mCheckedAction = tempAction;
    tempAction->setChecked(true);
    update();
    QWidget::mousePressEvent(event);
}


void SideBar::mouseMoveEvent(QMouseEvent *event)
{
    QAction* tempAction = actionAt(event->pos());
    if(tempAction == NULL){
        mOverAction = NULL;
        update();
        return;
    }
    if(tempAction->isChecked() || mOverAction == tempAction)
        return;
    mOverAction = tempAction;
    update();
    QWidget::mouseMoveEvent(event);
}

void SideBar::leaveEvent(QEvent * event)
{
    mOverAction = NULL;
    update();
    QWidget::leaveEvent(event);
}

QAction* SideBar::actionAt(const QPoint &at)
{
    int action_y = 0;
    for(auto action: mActions)
    {
        QRect actionRect(0, action_y, rect().width(), action_height);
        if(actionRect.contains(at))
            return action;
        action_y += actionRect.height();
    }
    return NULL;
}

#undef action_height

示例代码为here .

截图:

enter image description here

enter image description here

enter image description here

关于c++ - 用 C++ 设计 Qt Creator 的侧边栏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44317029/

相关文章:

c++ - 在另一个函数中使用函数内部声明的 vector

c++ - IDE字体间距问题

c++ - C/C++ 将编码设置为 UNICODE.. 如何将 'ă' 写入文件

c++ - 实现扫描线算法

multithreading - Qt:使用线程构造widgets

c++ - Qt 3d C++ 动画

c++ - qt 将数据库 sql 添加到从 cmake 导入的项目中

c++ - 如何使 QDialogBu​​ttonBox 不关闭其父 QDialog?

qt5 - 构建配置 "profile"有什么作用?

javascript - 如何在 Qt Creator 中捕获 QWebEngineView 中的 javascript 错误?