QListWidget öğeleri tutarlı konumlandırma sorunu

Aug 17 2020

Qt framework'te yeniyim. Yeni uygulamada özelleştirilmiş öğeler içeren liste oluşturmak istiyorum. Bu öğeler oldukça basittir ve başlık etiketi, küçük resim ve açıklama etiketi içermelidir ( burada resim )

Şimdilik özel çizim ve tüm bu şeyler ile oynamak istemiyorum çünkü istediğim öğeleri uygun widget / düzen ile yapmanın daha kolay olduğunu düşünüyorum, bu yüzden QListwidget ve alt sınıflara ayrılmış QAbstractItemModel (KeyframeModel) ve QListWidgetItem (TileWidgetItem) kullanmaya karar verdim.

Biraz kodlamadan sonra istediğim gibi görünüyor ama bazı öğeler eklediğimde QListWidget'e (ızgara modu) garip bir şey oluyor. Benim durumumda bir QListWidget yeniden boyutlandırılabilir (ana mizanpajın içine nasıl yerleştirildiği nedeniyle) ve sütun sayısı liste ve öğe genişliğine bağlı olmalıdır. Öğeler sabit boyuttadır (en azından şimdilik). Ancak listeyi yeniden boyutlandırdığımda, bir liste genişliğindeki öğelerden biri yanlış hizalanmış ve neler olduğunu bilmiyorum. Aşağıda uygulamadan te ekran görüntüleri verilmiştir:

Resim 1 Başlangıç ​​durumunu listeleyin (başladıktan hemen sonra)

Resim 2 # 1 yeniden boyutlandırıldıktan sonra liste

Resim 3 Yeniden boyutlandırdıktan sonra liste # 2

# 2'yi yeniden boyutlandırmak, # 1'i yeniden boyutlandırmaktan birkaç piksel daha geniştir ve # 1'i yeniden boyutlandırmak zordur (kenarlık durumu) - birkaç piksel genişliği daha az ve 2 sütunum var (sorun değil) ancak bazı pikseller daha fazla ve sonunda büyük / küçük harfle sonuçlanıyorum # 2. Her durumda sütun sayısında sorun yoktur.

Bazen burada olduğu gibi program hemen başladıktan sonra son öğe de yanlış hizalanır (resim 1'deki gibi başladıktan hemen sonra ancak aynı liste genişliğine rağmen farklı sonuçlar görebileceğiniz gibi). Başladıktan sonra neden bu kadar tutarsız olduğunu merak ediyorum.

Bir şey mi kaçırıyorum? Bazı bölümleri farklı şekilde mi yapmalıyım? Yoksa hata ayıklama modundaki bazı hatalar mı?

Aşağıda bazı kodlar yazıyorum:

Uygulama:

// Source file 

QtGuiApplication1::QtGuiApplication1(QWidget *parent) 
    : QMainWindow(parent)
{
    ui.setupUi(this);

    //--------------------------------------------------------------------------------
    // Add elements to the list

    TileWidgetItem *item = new TileWidgetItem();
    item->setData(TileWidgetItem::TileRole::TitleRole, QVariant("Long title"));
    item->setData(TileWidgetItem::TileRole::DescriptionRole, QVariant("My long info"));
    item->setText("My super text");
    qDebug() << "Widget size hint: " << item->sizeHint();

    ui.listWidget_moves->addItem(item);
    item->updateView();

    TileWidgetItem *item1 = new TileWidgetItem();
    item1->setData(TileWidgetItem::TileRole::TitleRole, QVariant("Item #2"));
    item1->setText("Tile #2");
    ui.listWidget_moves->addItem(item1);
    item1->updateView();

    TileWidgetItem *item2 = new TileWidgetItem();
    ui.listWidget_moves->addItem(item2);
    item2->updateView();

    TileWidgetItem *item3 = new TileWidgetItem();
    ui.listWidget_moves->addItem(item3);
    item3->updateView();

    //--------------------------------------------------------------------------------
    // Adjust cell size

    QSize cellSize;

    for (uint i = 0; i < ui.listWidget_moves->count(); i++)
    {
        int dim = ui.listWidget_moves->item(i)->sizeHint().height();

        if (dim > cellSize.height())
            cellSize.setHeight(dim);

        dim = ui.listWidget_moves->item(i)->sizeHint().width();

        if (dim > cellSize.width())
            cellSize.setWidth(dim);
    }

    ui.listWidget_moves->setGridSize(cellSize);
}

Öğe widget'ı:

// Source file

constexpr int MAX_THUMB_SIZE = 100;

TileWidgetItem::TileWidgetItem(QListWidget *listview)
    : QListWidgetItem(listview, ItemType::UserType)
{
    /* Prepare main widget */

    QWidget *view = new QWidget();
    view->setObjectName("tile");
    view->setStyleSheet(
        "QWidget#tile { margin: 4 8; background-color: #404040; border: 1 solid rgba(0,0,0,30%); border-radius: 4px }\n"
        "QWidget#tile::hover { border: 1 solid #EEE; background-color: #484848 }\n"
        "QWidget#tile[selected=true] { background-color: #00F }"
    );
    
    //-----------------------------------------------------------
    /* Prepare layout */

    QVBoxLayout *layout = new QVBoxLayout();
    layout->setSizeConstraint(QLayout::SizeConstraint::SetFixedSize);

    //-----------------------------------------------------------
    /* Prepare title with icon */

    QHBoxLayout *titleLayout = new QHBoxLayout();

    QLabel *titleIcon = new QLabel();
    titleIcon->setObjectName("titleIcon");
    titleIcon->setStyleSheet("background-color: black");
    titleIcon->setFixedSize(QSize(16, 16));
    titleLayout->addWidget(titleIcon);

    QLabel *title = new QLabel("Title");
    title->setObjectName("title");
    title->setMinimumWidth(60);
    title->setStyleSheet("background-color: #800;");
    titleLayout->addWidget(title);
    
    QWidget *titleWidget = new QWidget();
    titleWidget->setStyleSheet("background-color: #080");
    titleWidget->setLayout(titleLayout);

    layout->addWidget(titleWidget);

    //-----------------------------------------------------------
    /* Prepare thumbnail */
    
    QLabel *thumbnail = new QLabel();
    thumbnail->setObjectName("thumbnail");
    thumbnail->setStyleSheet("background-color: black; border: 1 solid #F00");
    thumbnail->setFixedSize(QSize(MAX_THUMB_SIZE, MAX_THUMB_SIZE * 0.7f));
    thumbnail->setPixmap(QPixmap("Resources/moto.jpg").scaledToWidth(MAX_THUMB_SIZE));
    layout->addWidget(thumbnail);
    
    //-----------------------------------------------------------
    /* Preparing additional info */

    QLabel *description = new QLabel("Description");
    description->setObjectName("description");
    //description->setToolTip("Custom info tip");
    description->setContentsMargins(4, 2, 4, 2);
    layout->addWidget(description);

    //-----------------------------------------------------------

    view->setLayout(layout);

    _customView = view;
    _titleView = title;
    _descriptionView = description;

    setSizeHint(_customView->sizeHint());

    updateView();
}

TileWidgetItem::~TileWidgetItem()
{
}

void TileWidgetItem::setData(int role, const QVariant &value)
{
    QListWidgetItem::setData(role, value);

    if (value.type() == QVariant::Type::String)
    {
        if (role == TileRole::TitleRole)
        {
            this->_titleView->setText(value.toString());
        }
        else if (role == TileRole::DescriptionRole)
        {
            this->_descriptionView->setText(value.toString());
        }

        setSizeHint(_customView->sizeHint());
    }
}

void TileWidgetItem::updateView()
{
    if (listWidget() != nullptr)
    {
        listWidget()->setItemWidget(this, this->_customView);
    }
}
// Header file

class TileWidgetItem : public QListWidgetItem
{
public:
    enum TileRole
    {
        TitleRole = Qt::UserRole + 1,
        DescriptionRole,
        ThumbnailRole
    };

public:
    TileWidgetItem(QListWidget *listview = nullptr);
    ~TileWidgetItem();

    void setData(int role, const QVariant &value) override;
    void updateView();

    QWidget *customView() const { return _customView; };

    QString getTitle() const { return _titleView->text(); };

    QString getInfo() const { return _descriptionView->text(); };

private:
    QWidget *_customView;
    QLabel *_titleView;
    QLabel *_descriptionView;
};

Platform: Windows 10
Qt sürümü: 5.14.2
IDE: Visual Studio 2019 (Qt VS Araçları ile)

Yanıtlar

KamilSzepietowski Sep 01 2020 at 18:23

Sonunda sorunları çözen özel temsilciler kullandım.

Sistemi aşırı kullanmak istedim ve yenildim :)