目录
- 前言
- 思路一
- 思路二
- 思路二缺陷
- 思路三
- 思路四
前言
楼主并没有完整的解决这个问题,如果你是着急寻找解决方案的就可以划走了,如果你对楼主的解决思路有兴趣,那么可以继续向下阅读。首先需求是可以控制QListWidgetItem
的icon和text x轴的位置,但是同时保持icon在左text在右的基本布局,还要求styleSheet能够生效。
思路一
做一张两边透明中间显示的图片。这样就可以控制icon和text的位置了。楼主没有试过实际效果
思路二
使用QListWIdget
的setItemWIdget
接口。
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
QListWidgetItem *item0 = new QListWidgetItem(ui->listWidget);
MyItemWidget *itemWidget = new MyItemWidget(QIcon(":/pic/rabbit.png"), QStringLiteral("兔子"), ui->listWidget);
ui->listWidget->setItemWidget(item0, itemWidget);
QListWidgetItem *item1 = new QListWidgetItem(ui->listWidget);
item1->setIcon(QIcon(":/pic/tiger.png"));
item1->setText(QStringLiteral("老虎"));
ui->listWidget->addItem(item0);
ui->listWidget->addItem(item1);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_pushButton_clicked()
{
QListWidgetItem *item = ui->listWidget->item(0);
QModelIndex index = ui->listWidget->currentIndex();
qDebug() << index.data(Qt::DisplayRole).toString();
}
MyItemWidget::MyItemWidget(const QIcon &icon, const QString &name, QWidget *parent)
{
iconLabel = new QLabel;
iconLabel->setPixmap(icon.pixmap(QSize(15, 15)));
iconLabel->setFixedSize(QSize(15, 15));
nameLabel = new QLabel(name);
hSpaceItem = new QSpacerItem(10, 10, QSizePolicy::Fixed);
hSpaceItem1 = new QSpacerItem(20, 10, QSizePolicy::Fixed);
layout = new QHBoxLayout;
layout->setMargin(0);
layout->addItem(hSpaceItem);
layout->addWidget(iconLabel);
layout->addItem(hSpaceItem1);
layout->addWidget(nameLabel);
this->setLayout(layout);
}
MyItemWidget::~MyItemWidget()
{
}
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QListWidget>
#include <QListWidgetItem>
#include <QIcon>
#include <QSpacerItem>
#include <QLabel>
#include <QHBoxLayout>
#include "mydelegate.h"
namespace Ui {
class MainWindow;
}
class MyItemWidget : public QWidget
{
Q_OBJECT
public:
explicit MyItemWidget(const QIcon& icon, const QString& name, QWidget *parent = nullptr);
~MyItemWidget();
private:
QLabel *iconLabel;
QLabel *nameLabel;
QSpacerItem *hSpaceItem;
QSpacerItem *hSpaceItem1;
QHBoxLayout *layout;
};
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void on_pushButton_clicked();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
思路二缺陷
因为对于QListWidget QTableWidget
等。如果在stylesheet中把为状态为selected
的item
背景色设置为深色那么前景色(字体的颜色)会变成比较浅的颜色来做一个区分。如果使用思路二那么将没有这种效果。
如果你想通过QlistWidget
点击某个item的信号来控制label的颜色,那么这是可行的。只是你可能会在遇到一个坑,那就是伪状态为:selected:!actived
没有进行控制。
思路三
通过delegate控制,将用于画图的rectangle左边缩短一截。这样导致的问题是,item区域有部分rectangle没法使用样式表控制,且只能控制icon相对于左侧的位置。
MyDelegate.cpp
#include "mydelegate.h"
#include <QDebug>
MyDelegate::MyDelegate(QObject *parent) : QStyledItemDelegate(parent)
{
}
void MyDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
// QPixmap icon = index.data(Qt::DecorationRole).value<QIcon>().pixmap(15 , option.rect.height() - 5);
// QString text = index.data(Qt::DisplayRole).toString();
// QAbstractItemModel *model = (QAbstractItemModel*)index.model();
// model->setData(index, QVariant::fromValue(QIcon()), Qt::DecorationRole);
// model->setData(index, QVariant::fromValue(QString()), Qt::DisplayRole);
// QStyleOptionViewItem op(option);
// QStyledItemDelegate::paint(painter, op, index);
// painter->drawPixmap(op.rect.x() + 5, op.rect.y() + 5, 15, op.rect.height() - 5, icon);
// painter->drawText(op.rect.x() + 5 + 15 + 30, op.rect.height() / 2, text);
QStyleOptionViewItem op(option);
op.rect = QRect(op.rect.x() + 30, op.rect.y(), op.rect.width(), op.rect.height());
QStyledItemDelegate::paint(painter, op, index);
}
思路四
通过delegate,让delegate不绘制icon和text。icon和text有自己来手动绘制。想法很美好但是现实根本行不通
MyDelegate.cpp
#include "mydelegate.h"
#include <QDebug>
MyDelegate::MyDelegate(QObject *parent) : QStyledItemDelegate(parent)
{
}
void MyDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
qDebug() << index.row();
QPixmap icon = index.data(Qt::DecorationRole).value<QIcon>().pixmap(15 , option.rect.height() - 5);
QString text = index.data(Qt::DisplayRole).toString();
QAbstractItemModel *model = const_cast<QAbstractItemModel*>(index.model());
model->setData(index, QVariant::fromValue(QIcon()), Qt::DecorationRole);
model->setData(index, QVariant::fromValue(QString()), Qt::DisplayRole);
QStyleOptionViewItem op(option);
painter->drawPixmap(op.rect.x() + 5, op.rect.y() + 5, 15, op.rect.height() - 5, icon);
painter->drawText(op.rect.x() + 5 + 15 + 30, op.rect.height() / 2, text);
QStyledItemDelegate::paint(painter, op, index);
}
思路四效果
效果就是没有任何效果。跪求大佬解答为什么没有效果。