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



  • 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



  • May you write what you're saying because I don't understand ?



  • #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


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.