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_H
Thank 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