我想要的是使用带有 QTreeView 的 qt 创建一个侧边栏,分支放在项目的右侧。像 AdminLTE 侧边栏:https ://adminlte.io/themes/AdminLTE/index2.html# 。
我尝试了几种解决方案,每一种都失败了我想要的设计:
- 使用委托
- 派生 TreeView 类并重新实现 DrawBranches
- 创建自定义 ProxyStyle
重点是我来自 Web 开发背景,用它做这些事情超级容易!
编辑:
假设我们有一个愚蠢的 ProxyStyle 派生类,我应该为以下情况做些什么:
void CustomStyle::drawPrimitive(PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const
{
if (element == PE_IndicatorBranch) {
// put this damn thing at right
}
else if(element == PE_PanelItemViewItem) {
// put this at left
}
// else
QProxyStyle::drawPrimitive(element, option, painter, widget);
}
或者也许使用委托:
void TreeItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
// for example translate branch!? what to do????
QStyledItemDelegate::paint(painter, option, index);
}
或者重新实现 TreeView::DrawBranches。无论哪种方式,都不知道该怎么做才能完全满足我的要求。
编辑2:
现在就是这样,但仍然不是我想要的,例如悬停会导致行为:
侧边栏.cpp
#include "sidebar.h"
#include <QMouseEvent>
#include <QPainter>
#include "sidebarstyle.h"
#include "sidebardelegate.h"
SideBar::SideBar(QWidget *parent)
: QTreeView(parent)
{
setStyle(new SideBarStyle);
setItemDelegate(new SideBarDelegate(this));
setHeaderHidden(true);
setEditTriggers(QAbstractItemView::NoEditTriggers);
// setIndentation(40);
resize(230, parent->height());
setSizePolicy(QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Expanding));
// QPalette palette;
// palette.setBrush(QPalette::Base, QColor(34, 45, 50));
// palette.setBrush(QPalette::Highlight, Qt::transparent);
// setPalette(palette);
setStyleSheet("QTreeView::item {height: 50px;} QTreeView {background-color: #222d32; color: #b8c7ce; font-size: 14px; font-weight: 400;} QTreeView::branch:selected, QTreeView::item:selected, QTreeView::branch:hover, QTreeView::item:hover {background-color: #1e282c; color: #fff}");
// setStyleSheet("QTreeView {background-color: #222d32; color: #b8c7ce}");
}
void SideBar::mousePressEvent(QMouseEvent *event)
{
QModelIndex index = indexAt(event->pos());
bool lastState = isExpanded(index);
QTreeView::mousePressEvent(event);
setExpanded(index, !lastState);
}
void SideBar::drawBranches(QPainter *painter, const QRect &rect, const QModelIndex &index) const
{
QTreeView::drawBranches(painter, rect, index);
}
sidebardelegate.cpp
#include "sidebardelegate.h"
#include <QPainter>
#include "state.h"
SideBarDelegate::SideBarDelegate(QObject *parent)
: QStyledItemDelegate(parent)
{
font.setFamily("FontAwesome");
font.setPixelSize(28);
}
void SideBarDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const {
QStyledItemDelegate::paint(painter, option, index);
if(index.column() == 0){
QRect _branch = QRect(option.widget->width() - option.decorationSize.width() -25, option.rect.y() + option.rect.height() / 4, option.decorationSize.width() + 15, option.rect.height() / 2);
// QRect icon = QRect(5, option.rect.y() + option.rect.height() / 4, option.decorationSize.width(), option.rect.height() / 2);
QModelIndex _index = index;
int depth = 0;
while ( _index.parent().isValid() )
{
_index = _index.parent();
depth++;
}
// if(index.parent().isValid()) {
QRect icon = QRect(5 + option.decorationSize.width() * depth, option.rect.y() + option.rect.height() / 4, option.decorationSize.width() + 10, option.rect.height() / 2);
// }
painter->setFont(font);
if(option.state & QStyle::State_Children)
{
if(option.state & QStyle::State_Open)
{
// painter->drawImage(_branch, QImage("/home/fisher/Pictures/Download.png"));
painter->drawText(_branch, "\uf107");
}
else
{
//painter->drawImage(_branch, QImage("/home/fisher/Pictures/135210286.png"));
painter->drawText(_branch, "\uf104");
}
switch (index.row()) {
case 0:
// painter->drawImage(icon, QImage("/home/fisher/Pictures/135210286.png"));
painter->drawText(icon, "\uf080");
break;
case 1:
// painter->drawImage(icon, QImage("/home/fisher/Pictures/images.png"));
painter->drawText(icon, "\uf14a");
break;
case 2:
// painter->drawImage(icon, QImage("/home/fisher/Pictures/iamges.jpeg"));
painter->drawText(icon, "\uf0c3");
break;
default:
// painter->drawImage(icon, QImage("/home/fisher/Pictures/images (1).png"));
painter->drawText(icon, "\uf085");
}
if(option.state & QStyle::State_Selected) {
QRect bar = QRect(0, option.rect.y(), 2, option.rect.height());
painter->setBrush(QColor(60, 141, 188));
painter->setPen(QColor(60, 141, 188));
painter->drawRect(bar);
}
} else {
adjustDefaultTextColors(option, *painter);
painter->drawText(icon, "\uf111");
//painter->drawImage(icon, QImage("/home/fisher/Pictures/images (1).jpeg"));
}
}
}
void SideBarDelegate::adjustDefaultTextColors(const QStyleOptionViewItem &option, QPainter &painter) const
{
if(option.state & QStyle::State_MouseOver) {
painter.setPen(QColor(255, 255, 255));
} else {
painter.setPen(QColor(138, 164, 175));
}
}
侧边栏样式.cpp
#include "sidebarstyle.h"
#include <QStyleFactory>
#include <QStyleOption>
#include <QColor>
SideBarStyle::SideBarStyle()
: QProxyStyle(QStyleFactory::create("linux"))
{
}
void SideBarStyle::drawPrimitive(PrimitiveElement element,
const QStyleOption *option,
QPainter *painter,
const QWidget *widget) const
{
if(element & PE_IndicatorBranch) {
return;
}
// if(option->state & QStyle::State_HasFocus){
// QStyleOptionViewItem myViewItemOption;
// const QStyleOptionViewItem *viewItemOption =
// qstyleoption_cast<const QStyleOptionViewItem *>(option);
// if (viewItemOption) {
// myViewItemOption = *viewItemOption;
// myViewItemOption.palette.setBrush(QPalette::Highlight, QColor(30, 40, 44));
// myViewItemOption.palette.setBrush(QPalette::HighlightedText, Qt::white);
// }
// QProxyStyle::drawPrimitive(element, &myViewItemOption, painter, widget);
// return;
// }
QProxyStyle::drawPrimitive(element, option, painter, widget);
}
//void SideBarStyle::drawControl(ControlElement element,
// const QStyleOption *option,
// QPainter *painter,
// const QWidget *widget) const
//{
//// if(option->state & QStyle::State_HasFocus){
//// QStyleOptionViewItem myViewItemOption;
//// const QStyleOptionViewItem *viewItemOption =
//// qstyleoption_cast<const QStyleOptionViewItem *>(option);
//// if (viewItemOption) {
//// myViewItemOption = *viewItemOption;
//// myViewItemOption.palette.setBrush(QPalette::Highlight, QColor(30, 40, 44));
//// myViewItemOption.palette.setBrush(QPalette::HighlightedText, Qt::white);
//// }
//// QProxyStyle::drawControl(element, &myViewItemOption, painter, widget);
//// return;
//// }
// QProxyStyle::drawControl(element, option, painter, widget);
//}
当前图片
我还从@eyllanesc 那里借了一些帮助来回答这个问题: How to remove QTreeView indentation