使点击的 QListWidgetItem 无边框

Making a clicked QListWidgetItem borderless

我有一个QListWidget子类widget处理鼠标事件,如下图:

当鼠标悬停在图标上时,它的项目会显示文字,悬停背景是透明的。单击后将自动清除选择,但悬停时我仍然在单击的项目周围得到一条虚线矩形:

我将样式表设置如下:

self.setStyleSheet("ListLabelWidget {background: transparent;border: borderless;}\
                    ListLabelWidget::item:hover {background-color: transparent;}")

如果我将悬停边框设置为无边框或 0px:

self.setStyleSheet("ListLabelWidget {background: transparent;border: borderless;}\
                    ListLabelWidget::item:hover {background-color: transparent;border: borderless;}")

矩形仍然显示在文本字段周围:

我应该怎么做才能完全隐藏它?

我找不到 qss 的任何解决方案,但可以用 QStyledItemDelegate 实现。这是 C++ 的示例。

首先为项目创建您自己的小部件。在我的示例中,我在设计器中创建了带有两个 QLabel 的简单小部件:用于图标和文本。并添加简单的数据设置方法

void ItemWidget::SetData(const QIcon &icon, const QString &text)
{
    ui->iconLabel->setPixmap(icon.pixmap(QSize(16,16)));
    ui->textLabel->setText(text);
}

然后继承 QStyledItemDelegate 并重新实现 paint 方法

class ListWidgetDelegate : public QStyledItemDelegate
{
    Q_OBJECT
public:
    explicit ListWidgetDelegate(QObject *parent = 0);

    void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
    {
        ItemWidget widget;
        widget.SetData(index.data(Qt::DecorationRole).value<QIcon>(),
                       index.data(Qt::DisplayRole).toString());
        widget.resize(option.rect.width(), option.rect.height());

        painter->drawPixmap(option.rect, QPixmap::grabWidget(&widget));
    }
};

如果您需要更大的项目,您也可以重新实现 sizeHint 方法。

最后为 QListWidget 设置项目和委托。

QIcon icon(":/crown.ico");
QListWidgetItem *item1 = new QListWidgetItem(icon, "Text1", ui->listWidget);
QListWidgetItem *item2 = new QListWidgetItem(icon, "Text2", ui->listWidget);
QListWidgetItem *item3 = new QListWidgetItem(icon, "Text3", ui->listWidget);
QListWidgetItem *item4 = new QListWidgetItem("No Icon", ui->listWidget);

ListWidgetDelegate *delegate = new ListWidgetDelegate(ui->listWidget);
ui->listWidget->setItemDelegate(delegate);

在此实现中,QListWidget::item

不需要 qss(样式表)