36 votes

QListView/QListWidget avec des éléments personnalisés

Je suis en train d'écrire ma première application Qt avec PyQt et vais avoir quelques problèmes lors de la création d'une liste personnalisée de vue. Je voudrais la liste arbitraire des widgets (un widget personnalisé en particulier). Comment pourrais-je aller à ce sujet?

Il semble que la solution serait de créer une table ou une grille enveloppé dans une barre de défilement. Cependant, j'aimerais être en mesure de prendre avantage de la modèle/vue de l'approche ainsi que la nidification (de l'arbre) en charge du haut-ins de la poignée.

EDIT: Pour préciser, ce widget est interactif (contient des boutons), de sorte que la solution exige plus que la peinture d'un widget.

31voto

Idan K Points 10037

Je pense que vous devez à la sous-classe QItemDelegate.

QItemDelegate peut être utilisé pour fournir affichage personnalisé des fonctionnalités et de l'éditeur des widgets pour le point de vue en fonction sur QAbstractItemView sous-classes. À l'aide d'un délégué à cette fin permet à l' l'affichage et la modification des mécanismes de personnalisé et développé de manière indépendante à partir du modèle et la vue.

Ce code est pris à partir de Qt exemples, l'application torrent.

class TorrentViewDelegate : public QItemDelegate
{
    Q_OBJECT
public:
    inline TorrentViewDelegate(MainWindow *mainWindow) : QItemDelegate(mainWindow) {}

    inline void paint(QPainter *painter, const QStyleOptionViewItem &option,
                      const QModelIndex &index ) const
    {
        if (index.column() != 2) {
            QItemDelegate::paint(painter, option, index);
            return;
        }

        // Set up a QStyleOptionProgressBar to precisely mimic the
        // environment of a progress bar.
        QStyleOptionProgressBar progressBarOption;
        progressBarOption.state = QStyle::State_Enabled;
        progressBarOption.direction = QApplication::layoutDirection();
        progressBarOption.rect = option.rect;
        progressBarOption.fontMetrics = QApplication::fontMetrics();
        progressBarOption.minimum = 0;
        progressBarOption.maximum = 100;
        progressBarOption.textAlignment = Qt::AlignCenter;
        progressBarOption.textVisible = true;

        // Set the progress and text values of the style option.
        int progress = qobject_cast<MainWindow *>(parent())->clientForRow(index.row())->progress();
        progressBarOption.progress = progress < 0 ? 0 : progress;
        progressBarOption.text = QString().sprintf("%d%%", progressBarOption.progress);

        // Draw the progress bar onto the view.
        QApplication::style()->drawControl(QStyle::CE_ProgressBar, &progressBarOption, painter);
    }
};

Fondamentalement, comme vous pouvez le voir, il vérifie si la colonne à peindre est d'un indice, si si il peint une barre de progression. Je pense que vous pouvez tricher un peu et au lieu d'utiliser un QStyleOption vous pouvez utiliser votre propre widget.

edit: ne pas oublier de configurer votre point délégué auprès de votre QListView à l'aide de setItemDelegate.

Lors de l'enquête à votre question, je suis tombé sur ce thread, qui analyse comment peindre un widget personnalisé à l'aide d'un QItemDelegate, je crois qu'il a toutes les informations dont vous pourriez avoir besoin.

5voto

sashoalm Points 10403

@Idan réponse fonctionne bien, mais je vais poster un exemple plus simple, je suis venu avec. De ce point délégué, tout dessine un rectangle noir pour chaque élément.

class ItemDelegate : public QItemDelegate
{
public:
    explicit ItemDelegate(QObject *parent = 0) : QItemDelegate(parent) {}
    void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
    {
        painter->fillRect(option.rect.adjusted(1, 1, -1, -1), Qt::SolidPattern);
    }
};

Et puis vous avez juste besoin de mettre pour la liste de widget:

ui->listWidget->setItemDelegate(new ItemDelegate(ui->listWidget));

2voto

Max Points 1759

Aider dit, que:

void QTableWidget::setCellWidget (int row, int column, QWidget * widget)  

Définit le widget est affiché dans la cellule dans la ligne et de la colonne, en passant la propriété du widget à la table. Si la cellule widget est remplacé par la cellule widget B, cellule widget sera supprimé.

Et il y a des analogues de cette méthode dans la plupart des QAbstractItemView descendants.

Vous avez à la sous-classe Q***Déléguer uniquement lorsque vous souhaitez éditeur widget apparaissent uniquement lorsque vous appuyez sur EditTrigger, puis disparaître et laisser délégué rendre l'affichage élément d'une certaine façon.

Si je corrige, tu voulais voir du contrôle au point de vue de tous les temps et être en mesure de frapper les contrôles sans avoir besoin d'entrer en mode d'édition et d'attendre que délégué crée de l'éditeur et de l'ensemble de son état, donc vous n'avez pas besoin de faire de délégué spécifique, il suffit de définir un widget dans la vue de l'élément.

1voto

sallu Points 210

une autre façon vous pouvez ajouter des éléments personnalisés dans listWidget. pour ce faire, vous devez ajouter une nouvelle classe. le nom que vous voulez que je viens de lui donner "maliste" j'espère que vous savez comment faire pour ajouter de nouveaux éléments dans le projet. :)

alors dans ce nouveau cadre ajouter votre contrôle autant que tu veux. comme QLabels,QlineEdit etc

puis dans la classe principale de u ont pour ajouter un listWidget nom de la liste ou que vous le souhaitez et de les écrire le code suivant

    MyList *myList = new MyList();
    QListWidgetItem *item = new QListWidgetItem();
    ui->list->insertItem(ui->list->size().height(),item);
    item->setSizeHint(QSize(50,30));
    ui->list->setItemWidget(item,myList);

dernier u pouvez également modifier les propriétés des éléments à l'aide de signaux/slots ..

espère que sa vous aider ..!

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X