Je suis sur un projet utilisant l'architecture MV de Qt avec une QListView pour afficher une liste de musiques. Actuellement la liste ressemble à l'image en bas de post. Seulement c'est moche et pas très utile pour donner des infos, j'aimerai faire un truc plus stylisé pour afficher l'image de l'album, les artistes et le chemin du ficher.
Sauf que je n'ai pas trouvé de moyen pour remplacer le widget par défaut qui est utilisé pour l'affichage d'un élément de la liste.
Les deux principales réponses sur le net sont :
utiliser la méthode paint de QStyledItemDelegate mais ça de permet pas de remplacer le widget, juste de le styliser et ça compliquerai la tâche pour ajouter d'autres éléments (pas de QLabel ou de layout il faut tout faire à la main, et pas d'interactivité).
Utiliste un QListWidget mais je perd tous les avantages la QListView qui fonctionne avec l'architecture MV de Qt.
Je suppose qu'il doit tout de même y avoir un moyen donc je tente ma chance ici, en espérant que des âmes éclairées m'aideront
Salutations
- Edité par Choucroute_melba 24 novembre 2024 à 23:47:07
Quand il n'y a pas de solution c'est qu'il n'y a pas de problème.
En fait, il faudrait commencer par créer tes propres widgets:
un qui contiendrait les widgets te permetttant de présenter les inforamtions relatives à un seul morceau (image de l'album, le titre de l'album, le titre de la chancon, le groupe, tout ce que tu veux)
et un qui contiendrait la liste des morceaux en elle-même, et qui rajouterait automatiquement le premier widget dont je viens de parler lorsque tu rajoute un morceau à cette play-liste.
Tu as, a priori, deux manières d'arriver à créer ces widgets : en passant par QtDesigner, qui te permettra de voir directement la forme que prend ta création, mais qui est "plus difficile" à utiiser dans un contexte complexe (comme le fait de rajouter un widget automatiquement) ou, "simplement" en créant une bonne vieille classe en C++, qui hérite de QWidget, et dans laquelle tu rajoute "tout ce que tu veux".
L'inconvénient de cette méthode est que tu travailleras plus ou moins "en aveugle" pour le positionnement des différentes parties, car tu ne pourras voir le résultat "effectif" qu'une fois ton code compilé.
En outre, comme la deuxième solution consiste à écrire du code soi-même, cela pourrait bien prendre "un peu plus plus de temps" que la première
En tout état de cause, il serait intéressant (surtout pour nous, si tu veux que l'on puisse t'aider efficacement) de faire une sorte de "modèle" du résultat que tu veux obtenir, quitte à ce que ce soit fait rapidement au crayon sur une feuille volante
Ce qui se conçoit bien s'énonce clairement. Et les mots pour le dire viennent aisément.Mon nouveau livre : Coder efficacement - Bonnes pratiques et erreurs à éviter (en C++)Avant de faire ce que tu ne pourras défaire, penses à tout ce que tu ne pourras plus faire une fois que tu l'auras fait
Si j'ai bien compris tu me proposes de créer moi-même une liste un peut comme ça ?
#include <QWidget> #include <QVBoxLayout> #include "TracksListModel.h" #include "widgets/TitleWidget.h" class TracksListWidget : public QWidget { Q_OBJECT
public: explicit TracksListWidget(QWidget *parent, TracksListModel *model) : QWidget(parent), m_model(model) { QVBoxLayout *layout = new QVBoxLayout(this); for (int i = 0; i < m_model->rowCount(); i++) { Title title = m_model->data(m_model->index(i), Qt::UserRole).value<Title>(); // TitleWidget = le widget perso que je veux mettre dans la liste layout->addWidget(new TitleWidget(this, title)); } }
private: TracksListModel *m_model; };
Sauf qu'avec cette approche je suis obligé de réimplémenter tout ce que QListView fait pour moi pour interagir avec le modèle...
C'est là que ça pêche, pour moi la solution la plus simple aurait été de changer le widget utilisé par QListView mais apparemment Qt n'offre pas cette possibilité... A moins de bricoler ?
Mon idée c'est de faire un truc dans ce genre, mais avec des infos différentes (toute dispo dans une ligne de TracksListModel) :
- Edité par Choucroute_melba 25 novembre 2024 à 13:58:42
Quand il n'y a pas de solution c'est qu'il n'y a pas de problème.
QListWidget est un QListView avec un modele standard en interne. C'est juste une commodité pour ne pas avoir a creer séparément la vue et le modèle. Mais c'est pareil.
A priori, ce que tu veux faire se fait bien avec un QStyledItemDelegate (je n'ai pas utilisé les widgets depuis longtemps). Il faut juste creer un "editor" spécifique, qui sera le widget que tu veux utiliser pour chaque ligne.
Salut, En effet la classe QListWidget hérite de QListView et me permet de mettre des widgets perso en faisant ça :
TracksListModel *model = new TracksListModel(); QListWidget *view = new QListWidget(this); TracksListDelegate *delegate = new TracksListDelegate(view); for (int i = 0; i < model->rowCount(); i++) { Title title = model->data(model->index(i, 0), Qt::UserRole).value<Title>(); QListWidgetItem *item = new QListWidgetItem(view); view->addItem(item); QLabel *label = new QLabel(title.fileName); view->setItemWidget(item, label); }
Seulement avec cette solution je ne peux pas mettre mon modèle perso (TracksListModel) donc je perd de toutes façons l'avantage de la QListView qui réagissait avec le modèle. Je ne comprend pas trop pourquoi Qt ne permet pas de changer de widget dans la View si ils l'ont fait dans la QListWidget...
gbdivers a écrit:
A priori, ce que tu veux faire se fait bien avec un QStyledItemDelegate (je n'ai pas utilisé les widgets depuis longtemps). Il faut juste creer un "editor" spécifique, qui sera le widget que tu veux utiliser pour chaque ligne.
Oui mais du coup l'éditor c'est un widget pour éditer la valeur d'une ligne. Pour contrôler ce qui est affiché par défaut, c'est la méthode paint et elle ne permet pas d'utiliser les widgets et les layouts.
Donc au final je suppose que je n'ai pas d'autres choix que de faire une sous-classe de QListView avec mon modèle ? Par contre je n'ai aucune idée de comment m'y prendre...
- Edité par Choucroute_melba 26 novembre 2024 à 15:26:49
Quand il n'y a pas de solution c'est qu'il n'y a pas de problème.
Attention, quand je disais "qui hérite de QWidget", en réalité, je voulais dire "qui hérite de n'importe quelle classe héritant déjà de QWidget qui soit adapté à tes besoins"...
Donc, pour la représentation d'un morceau particulier, ce pourrait être une classe qui hérite de QListWidgetItem et, pour la liste en elle-même, une classe qui dérive de QListWidget (si elle ne suffit pas en elle-même), voir de QListView.
Il n'y a -- en effet -- aucune raison de partir d'un QWidget, qui a la possibilité de tout faire, mais qui ne fait rien par lui même (ou, du moins, qui ne fait pas grand chose par lui-même), alors que des classes spécialisées dans certains traitement (comme QListWidget et QListWidgetItem) prennent "naturellement" en charge une grande partie des comportements que tu es en droit d'attendre de la part de tes classes perso
Ceci dit, c'est ma faute : j'aurais du le préciser dés le départ. Et pourtant, cela me paraissait tellement logique
D'ailleurs, il se peut tout à fait que les classes dont je viens de parler ne correspondent pas tout à fait à tes besoins ou à ta situation spécifique. Qu'à cela ne tienne, tu dispose d'une liste de classes susceptible d'être utilisée comme base pour tes widgets perso des plus importantes et que tu peux consulter ==> ICI <== .
Ce serait un monde si tu n'y trouvais pas une classe sur laquel tu puisse baser ton travail
Ce qui se conçoit bien s'énonce clairement. Et les mots pour le dire viennent aisément.Mon nouveau livre : Coder efficacement - Bonnes pratiques et erreurs à éviter (en C++)Avant de faire ce que tu ne pourras défaire, penses à tout ce que tu ne pourras plus faire une fois que tu l'auras fait
C'est justement ce que je me demandais si il n'y avait pas moyen d'hériter d'une class QListView ou autre pour afficher tes widgets persos dans la liste tout en gardant l'avantage d'une liste et d'un modèle.
Maintenant je ne connais pas très bien Qt. Ca fait longtemps que je n'ai plus utilisé Qt.
- Edité par OmbreNoire 28 novembre 2024 à 17:55:18
Ce serait un monde si tu n'y trouvais pas une classe sur laquel tu puisse baser ton travail
en effet il y a de quoi faire
Ceci dit je ne connaît pas très bien Qt et je trouve parfois difficile de savoir quelles fonctions réimplémenter et comment.
Mais finalement j'ai fait une sous classe de QAbstractItemView, ça a demandé un peut de travail pour faire un truc fonctionnel (et encore pas forcément propre) et j'ai pas mal galéré à faire l'UI (sans Qt designer du coup). Je suppose que c'était le meilleur compromis que je pouvais faire, sinon j'ai aucune idée de comment m'y prendre avec une QListeView ou widget...
Je vous met le code en fin de post, je veux bien des retours si possible
Quand il n'y a pas de solution c'est qu'il n'y a pas de problème.
Quand il n'y a pas de solution c'est qu'il n'y a pas de problème.
Discord NaN. Mon site.
Quand il n'y a pas de solution c'est qu'il n'y a pas de problème.
Quand il n'y a pas de solution c'est qu'il n'y a pas de problème.