Link two QListWidget
-
Hello !
I want to link two QListWidget, but I don't know how to do with code. I want that the user, in the first QListWidget, selects one QListWidgetItem and in the second QListWidget, for the selected QListWidgetItem of the first QListWidget, he can add many QListWidgetItem. When I select another QListWidgetItem in the first QListWidget, there is an update of the second QListWidget with the QListWidgetItems corresponding to the QListWidgetItem selected in the first QListWidget.
Example :
- First QListWidget - - Second QListWidget -
Hello -------------------------> Bonjour
|->Hey
|->Hi
GoodBye ---------------------> Ciao
|->Arivederci
|->Tchuss
My code is like :
secondwindow.cpp
#include "secondwindow.h" #include "ui_secondwindow.h" SecondWindow::SecondWindow(QWidget *parent) : QWidget(parent), ui(new Ui::SecondWindow) { ui->setupUi(this); ui->button_1->setIcon(QIcon(":/Images/Images/Haut.png")); ui->button_2->setIcon(QIcon(":/Images/Images/Bas.png")); ui->button_5->setIcon(QIcon(":/Images/Images/Haut.png")); ui->button_6->setIcon(QIcon(":/Images/Images/Bas.png")); connect(ui->button_1, SIGNAL(clicked()), this, SLOT(UpForLeft())); connect(ui->button_2, SIGNAL(clicked()), this, SLOT(DownForLeft())); connect(ui->button_3, SIGNAL(clicked()), this, SLOT(DeleteForLeft())); connect(ui->button_4, SIGNAL(clicked()), this, SLOT(AddForLeft())); connect(ui->button_10, SIGNAL(clicked()), this, SLOT(close())); connect(ui->table_1, SIGNAL(itemDoubleClicked(QListWidgetItem *)), this, SLOT(EditForLeft(QListWidgetItem *))); } SecondWindow::~SecondWindow() { delete ui; } void SecondWindow::UpForLeft() { QListWidgetItem *item; int i; i = ui->table_1->currentRow(); item = ui->table_1->takeItem(i); ui->table_1->insertItem(i - 1, item); ui->table_1->setCurrentRow(i - 1); } void SecondWindow::DownForLeft() { QListWidgetItem *item; int i; i = ui->table_1->currentRow(); item = ui->table_1->takeItem(i); ui->table_1->insertItem(i + 1, item); ui->table_1->setCurrentRow(i + 1); } void SecondWindow::UpForRight() { QListWidgetItem *item; int i; i = ui->table_2->currentRow(); item = ui->table_2->takeItem(i); ui->table_1->insertItem(i - 1, item); ui->table_1->setCurrentRow(i - 1); } void SecondWindow::DownForRight() { QListWidgetItem *item; int i; i = ui->table_2->currentRow(); item = ui->table_2->takeItem(i); ui->table_1->insertItem(i + 1, item); ui->table_1->setCurrentRow(i + 1); } void SecondWindow::AddForLeft() { QString string; string = ui->line_1->text(); ui->table_1->addItem(string); ui->line_1->clear(); } void SecondWindow::DeleteForLeft() { QListWidgetItem *item; int i; i = ui->table_1->currentRow(); item = ui->table_1->takeItem(i); delete item; } void SecondWindow::EditForLeft(QListWidgetItem *item) { item->setFlags(item->flags() | Qt::ItemIsEditable); item = ui->table_1->currentItem(); ui->table_1->editItem(item); }secondwindow.h
#ifndef SECONDWINDOW_H #define SECONDWINDOW_H #include <QListWidgetItem> #include <QWidget> #include <QString> #include <QIcon> namespace Ui { class SecondWindow; } class SecondWindow : public QWidget { Q_OBJECT public: explicit SecondWindow(QWidget *parent = 0); ~SecondWindow(); public slots: void UpForLeft(); void DownForLeft(); void UpForRight(); void DownForRight(); void AddForLeft(); void DeleteForLeft(); void EditForLeft(QListWidgetItem *item); private: Ui::SecondWindow *ui; }; #endif // SECONDWINDOW_HThank you for help
- First QListWidget - - Second QListWidget -
-
What you need is just to decouple QListWidget into model and view.
Use a QStandardItemModel as a tree, the top level having the first list and the second list as child. then set up the two listviews and use
setRootIndex()to determine what to display in the second one -
#include <QWidget> #include <QStandardItemModel> #include <QListView> #include <QHBoxLayout> class ModelViewExample : public QWidget { Q_OBJECT public: explicit ModelViewExample(QWidget *parent = nullptr) : QWidget(parent) { m_model = new QStandardItemModel(this); m_model->insertColumn(0); // Populate the model m_model->insertRows(0, 2); m_model->setData(m_model->index(0, 0), "Hello"); m_model->setData(m_model->index(1, 0), "Goodbye"); m_model->insertColumn(0, m_model->index(0, 0)); m_model->insertRows(0, 3, m_model->index(0, 0)); m_model->setData(m_model->index(0, 0, m_model->index(0, 0)), "Bonjour"); m_model->setData(m_model->index(1, 0, m_model->index(0, 0)), "Hey"); m_model->setData(m_model->index(2, 0, m_model->index(0, 0)), "Hi"); m_model->insertColumn(0, m_model->index(1, 0)); m_model->insertRows(0, 3, m_model->index(1, 0)); m_model->setData(m_model->index(0, 0, m_model->index(1, 0)), "Ciao"); m_model->setData(m_model->index(1, 0, m_model->index(1, 0)), "Arivederci"); m_model->setData(m_model->index(2, 0, m_model->index(1, 0)), "Tchuss"); m_list1 = new QListView(this); m_list1->setModel(m_model); m_list2 = new QListView(this); m_list2->setModel(m_model); connect(m_list1->selectionModel(), &QItemSelectionModel::currentChanged, this, &ModelViewExample::firstListSelected); QHBoxLayout* mainLay = new QHBoxLayout(this); mainLay->addWidget(m_list1); mainLay->addWidget(m_list2); firstListSelected(QModelIndex()); } virtual ~ModelViewExample()=default; protected slots: void firstListSelected(const QModelIndex& idx){ if (idx.isValid()) { Q_ASSERT(idx.model() == m_model); Q_ASSERT(!idx.parent().isValid()); // make sure idx comes from the top level m_list2->setRootIndex(idx); const int rowsToShow = m_model->rowCount(idx); for (int i = 0; i < rowsToShow; ++i) m_list2->setRowHidden(i, false); } else { const int rowsToHide = m_model->rowCount(m_list2->rootIndex()); for (int i = 0; i < rowsToHide; ++i) m_list2->setRowHidden(i, true); } } private: QAbstractItemModel* m_model; QListView* m_list1; QListView* m_list2; };For more info on models and views see http://doc.qt.io/qt-5/modelview.html