在C中设计Qt Creator的SideBar

我创建了一个用于创建侧边栏的类,就像在Qt Creator中一样(左边一个).我现在不知道让它看起来像Qt创建者那样,因为我看起来很难看!

侧边栏:

#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

sidebar.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);
}

这是我想要的:

在C中设计Qt Creator的SideBar

这是我得到的一个:

在C中设计Qt Creator的SideBar

解决方法:

一种可能的解决方案是使用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.

截图:

在C中设计Qt Creator的SideBar

在C中设计Qt Creator的SideBar

在C中设计Qt Creator的SideBar

上一篇:c – Qt5是否有类似StringBuilder或StringBuffer的类?


下一篇:c – 带动态添加小部件的QScrollArea