c++qtqlistwidgetitem

Get the coordinates of the QListWidgetItem x y, I want to achieve the effect shown in the figure


My code is as follows. After clicking the item with the mouse, I want a checkbox to be selected and show the background of the specified position and setting the checkbox Hope someone give a good suggestion and thank you

jobDialog::jobDialog(QWidget *parent) : QDialog(parent), ui(new Ui::jobDialog)
{
        ui->setupUi(this);
        ui->listWidget->setViewMode(QListView::IconMode);//
        ui->listWidget->setIconSize(QSize(300, 300));
        ui->listWidget->setSpacing(10);
        ui->listWidget->setResizeMode(QListWidget::Adjust);
        ui->listWidget->setMovement(QListWidget::Static);

        connect(ui->listWidget, SIGNAL(itemClicked(QListWidgetItem *)), this,
            SLOT(getItems(QListWidgetItem *)));

        int n = 10;
        for (int i = 0; i < n; i++) {

            QListWidgetItem *newItem = new QListWidgetItem(
                QIcon(":/res/images/video.png"), " iamges");
            newItem->setSizeHint(QSize(140, 130)); 

            newItem->setTextAlignment(Qt::AlignCenter);;

            ui->listWidget->addItem(newItem);
        }
}

void jobDialog::getItems(QListWidgetItem *item)
{   

        for (int i = 0; i < 10; i++) {
        if (ui->listWidget->item(i) == item) {

        }
    }
}


Solution

  • To paint a checkbox on the items you can use a QProxyStyle by enabling the checked property of the item, the status of the checkbox is changed through a delegate:

    proxystyle.h

    #ifndef PROXYSTYLE_H
    #define PROXYSTYLE_H
    
    #include <QPainter>
    #include <QProxyStyle>
    #include <QStyleOptionViewItem>
    
    class ProxyStyle: public QProxyStyle{
    public:
        using QProxyStyle::QProxyStyle;
        void drawControl(ControlElement element, const QStyleOption *opt, QPainter *p, const QWidget *w) const{
            QProxyStyle::drawControl(element, opt, p, w);
            if(element == QStyle::CE_ItemViewItem){
                if(const QStyleOptionViewItem *vopt = qstyleoption_cast<const QStyleOptionViewItem *>(opt)){
                    if(vopt->checkState == Qt::Checked)
                        drawCheckBox(*vopt, p);
                }
            }
        }
    private:
        void drawCheckBox(const QStyleOptionViewItem & option, QPainter *painter) const{
            QIcon::Mode mode = QIcon::Normal;
            if (!(option.state & QStyle::State_Enabled))
                mode = QIcon::Disabled;
            else if (option.state & QStyle::State_Selected)
                mode = QIcon::Selected;
            QIcon::State state = option.state & QStyle::State_Open ? QIcon::On : QIcon::Off;
            // load icon
            QIcon icon = standardIcon(QStyle::SP_DialogApplyButton);
            // or QIcon icon("/path/of/icon");
            const int size = 16;
            const int margin = 10;
            painter->save();
            QRect iconRect = QRect(option.rect.bottomRight() - (size + margin) * QPoint(1, 1), size * QSize(1, 1));
            icon.paint(painter, iconRect, Qt::AlignCenter, mode, state);
            painter->restore();
        }
    };
    
    #endif // PROXYSTYLE_H
    

    styleditemdelegate.h

    #ifndef STYLEDITEMDELEGATE_H
    #define STYLEDITEMDELEGATE_H
    
    #include <QEvent>
    #include <QMouseEvent>
    #include <QStyledItemDelegate>
    
    class StyledItemDelegate: public QStyledItemDelegate{
    public:
        using QStyledItemDelegate::QStyledItemDelegate;
        bool editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index){
            Qt::ItemFlags flags = model->flags(index);
            if (!(flags & Qt::ItemIsUserCheckable) || !(option.state & QStyle::State_Enabled)
                    || !(flags & Qt::ItemIsEnabled))
                return false;
            QVariant value = index.data(Qt::CheckStateRole);
            if (!value.isValid())
                return false;
            if ((event->type() == QEvent::MouseButtonRelease)
                    || (event->type() == QEvent::MouseButtonDblClick)
                    || (event->type() == QEvent::MouseButtonPress)) {
                if ((event->type() == QEvent::MouseButtonPress)
                        || (event->type() == QEvent::MouseButtonDblClick))
                    return true;
                Qt::CheckState state = static_cast<Qt::CheckState>(value.toInt());
                if (flags & Qt::ItemIsUserTristate)
                    state = ((Qt::CheckState)((state + 1) % 3));
                else
                    state = (state == Qt::Checked) ? Qt::Unchecked : Qt::Checked;
                return model->setData(index, state, Qt::CheckStateRole);
            }
            return false; //QStyledItemDelegate::editorEvent(event, model, option, index);
        }
    protected:
        void initStyleOption(QStyleOptionViewItem *option, const QModelIndex &index) const{
            QStyledItemDelegate::initStyleOption(option, index);
            // disable draw checkbox
            option->features &= ~QStyleOptionViewItem::HasCheckIndicator;
        }
    };
    
    #endif // STYLEDITEMDELEGATE_H
    
    // ...
    #include "proxystyle.h"
    #include "styleditemdelegate.h"
    // ...
    
    jobDialog::jobDialog(QWidget *parent) : QDialog(parent), ui(new Ui::jobDialog)
    {
        ui->setupUi(this);
        ui->listWidget->setViewMode(QListView::IconMode);//
        ui->listWidget->setIconSize(QSize(300, 300));
        ui->listWidget->setSpacing(10);
        ui->listWidget->setResizeMode(QListWidget::Adjust);
        ui->listWidget->setMovement(QListWidget::Static);
    
        ui->listWidget->setStyle(new ProxyStyle(ui->listWidget->style()));
        ui->listWidget->setItemDelegate(new StyledItemDelegate(ui->listWidget));
    
        int n = 10;
        for (int i = 0; i < n; i++) {
            QListWidgetItem *newItem = new QListWidgetItem(QIcon(":/res/images/video.png"), "");
            newItem->setSizeHint(QSize(140, 130)); 
            newItem->setTextAlignment(Qt::AlignCenter);
            newItem->setFlags(item->flags() | Qt::ItemIsUserCheckable);
            newItem->setCheckState(Qt::Unchecked);
            ui->listWidget->addItem(newItem);
        }
    
    }