Qt 从列表中选择项目到其他列表的实现(双列表、累加器、列表构建器、TwoListSelection ...) [英] Qt Implementation of selecting items from list into other list (Dual List, Accumulator, List builder, TwoListSelection ...)

查看:75
本文介绍了Qt 从列表中选择项目到其他列表的实现(双列表、累加器、列表构建器、TwoListSelection ...)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想从任意长度的列表中选择任意数量的项目.下拉列表 (QComboBox) 不允许检查项目.可检查项目的列表会因项目过多而变得笨拙.

我发现了

在下面的链接中,您会找到一个完整示例.

I want to select an arbitrary amount of items from a list of arbitrary length. A dropdown (QComboBox) doesn't allow checkable items. A list of checkable items would become clumsy with a lot of items.

I found this question in the User Experience SE subsite and this answer seems to be the solution that best suits my needs. It has many names, as a comment in said answer remarks: Dual List, Accumulator, List builder, TwoListSelection ...

The version from OpenFaces.org shown in the answer linked above:

I couldn't find an implementation in Qt, though. Should I implement it myself or is there an implementation available in Qt? Is there a recommended approach?

解决方案

This widget does not come by default in Qt, but it is not complicated to build it, the first thing you should do is list the requirements:

  • The button with text >> is enabled if the list on the left is not empty, if pressed it must move all the items.

  • The button with text << similar to the previous one but with the list on the right

  • The button with text > is enabled if an item in the list on the left is selected, if pressed, the selected item should be moved to the right one.

  • The button with text < the same but for the right side.

  • The button with "up" text is enabled if an item is selected and this is not the first item in the list. when pressed you must move the current item to a higher position.

  • The button with "down" text is enabled if an item is selected and this is not the last item in the list. when pressed you must move the current item to a lower position.

As we see most of the logic depends on the selection of items, for this we connect the signal itemSelectionChanged with the slot that decides whether the buttons are enabled or not.

To move items we must use takeItem() and addItem(), the first removes the item and the second adds it.

Moving up or down is equivalent to removing the item and then inserting it, for this we use takeItem() again with insertItem()

All the above is implemented in the following widget:

#ifndef TWOLISTSELECTION_H
#define TWOLISTSELECTION_H

#include <QHBoxLayout>
#include <QListWidget>
#include <QPushButton>
#include <QWidget>

class TwoListSelection : public QWidget
{
    Q_OBJECT
public:
    explicit TwoListSelection(QWidget *parent = nullptr):QWidget{parent}{
        init();
        connections();
    }

    void addAvailableItems(const QStringList &items){
        mInput->addItems(items);
    }

    QStringList seletedItems(){
        QStringList selected;
        for(int i=0; i<mOuput->count(); i++)
            selected<< mOuput->item(i)->text();
        return selected;
    }
private:
    void init(){
        QHBoxLayout *layout = new QHBoxLayout(this);
        mInput = new QListWidget;
        mOuput = new QListWidget;

        mButtonToSelected = new QPushButton(">>");
        mBtnMoveToAvailable= new QPushButton(">");
        mBtnMoveToSelected= new QPushButton("<");
        mButtonToAvailable = new QPushButton("<<");

        layout->addWidget(mInput);

        QVBoxLayout *layoutm = new QVBoxLayout;
        layoutm->addItem(new QSpacerItem(10, 20, QSizePolicy::Minimum, QSizePolicy::Expanding));
        layoutm->addWidget(mButtonToSelected);
        layoutm->addWidget(mBtnMoveToAvailable);
        layoutm->addWidget(mBtnMoveToSelected);
        layoutm->addWidget(mButtonToAvailable);
        layoutm->addItem(new QSpacerItem(10, 20, QSizePolicy::Minimum, QSizePolicy::Expanding));

        layout->addLayout(layoutm);
        layout->addWidget(mOuput);

        mBtnUp = new QPushButton("Up");
        mBtnDown = new QPushButton("Down");

        QVBoxLayout *layoutl =  new QVBoxLayout;
        layoutl->addItem(new QSpacerItem(10, 20, QSizePolicy::Minimum, QSizePolicy::Expanding));
        layoutl->addWidget(mBtnUp);
        layoutl->addWidget(mBtnDown);
        layoutl->addItem(new QSpacerItem(10, 20, QSizePolicy::Minimum, QSizePolicy::Expanding));

        layout->addLayout(layoutl);
        setStatusButton();
    }

    void connections(){
        connect(mOuput, &QListWidget::itemSelectionChanged, this, &TwoListSelection::setStatusButton);
        connect(mInput, &QListWidget::itemSelectionChanged, this, &TwoListSelection::setStatusButton);
        connect(mBtnMoveToAvailable, &QPushButton::clicked, [=](){
           mOuput->addItem(mInput->takeItem(mInput->currentRow()));
        });

        connect(mBtnMoveToSelected, &QPushButton::clicked, [=](){
           mInput->addItem(mOuput->takeItem(mOuput->currentRow()));
        });

        connect(mButtonToAvailable, &QPushButton::clicked, [=](){
            while (mOuput->count()>0) {
                 mInput->addItem(mOuput->takeItem(0));
            }
        });

        connect(mButtonToSelected, &QPushButton::clicked, [=](){
            while (mInput->count()>0) {
                 mOuput->addItem(mInput->takeItem(0));
            }
        });

        connect(mBtnUp, &QPushButton::clicked, [=](){
            int row = mOuput->currentRow();
            QListWidgetItem *currentItem = mOuput->takeItem(row);
            mOuput->insertItem(row-1, currentItem);
            mOuput->setCurrentRow(row-1);
        });

        connect(mBtnDown, &QPushButton::clicked, [=](){
            int row = mOuput->currentRow();
            QListWidgetItem *currentItem = mOuput->takeItem(row);
            mOuput->insertItem(row+1, currentItem);
            mOuput->setCurrentRow(row+1);
        });
    }

    void setStatusButton(){
        mBtnUp->setDisabled(mOuput->selectedItems().isEmpty() || mOuput->currentRow() == 0);
        mBtnDown->setDisabled(mOuput->selectedItems().isEmpty() || mOuput->currentRow() == mOuput->count()-1);
        mBtnMoveToAvailable->setDisabled(mInput->selectedItems().isEmpty());
        mBtnMoveToSelected->setDisabled(mOuput->selectedItems().isEmpty());
    }

    QListWidget *mInput;
    QListWidget *mOuput;

    QPushButton *mButtonToAvailable;
    QPushButton *mButtonToSelected;

    QPushButton *mBtnMoveToAvailable;
    QPushButton *mBtnMoveToSelected;

    QPushButton *mBtnUp;
    QPushButton *mBtnDown;
};

#endif // TWOLISTSELECTION_H

In the following link you will find a complete example.

这篇关于Qt 从列表中选择项目到其他列表的实现(双列表、累加器、列表构建器、TwoListSelection ...)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆