2016-11-03 6 views
1

나는 두 QListWidget를 연결하려면,하지만 난 코드와 함께 할 방법을 모르겠어요. 여기에 내가 무슨 짓을 : 이 Help 우리는 두 QListWidget을 볼 수 있습니다. 왼쪽 QListWidget에서 3 개의 QListWidgetItem을 추가합니다 (예 : "Bonjour", "Hello", "Tag"). 나는 ("화", "바스", "비엔" "봉쥬르", 예에 의해) 내가 올바른 QListWidget와 QListWidgetItem을 추가 할 수 있습니다 왼쪽 QListWidget 세 QListWidgetItem 중 하나를 클릭하면 것을 원한다. 3 개의 QListWidgetItem 중 하나를 클릭하지 않으면 오른쪽 QListWidget과 함께 QListWidgetItem을 추가 할 수 없습니다. "Bonjour": "Tu", "Vas", "Bien"및 "Hello"(분명히 "Hello"는 아무것도 포함하지 않음)를 클릭하면 오른쪽 QListWidget에 아무 것도 없습니다. 그것은 내가하고 싶은 일의 예일뿐입니다. 그것이 도움이 있다면 아래, 내 코드를 작성 :연결이 QListWidget

- secondwindow.h - - secondwindow.cpp -

#include "secondwindow.h" 
#include "ui_secondwindow.h" 
#include "thirdwindow.h" 
#include "ui_thirdwindow.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_9, SIGNAL(clicked()), this, SLOT(ShowThirdWindow())); 
    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::ShowThirdWindow() 
{ 
    ThirdWindow *window = new ThirdWindow; 

    window->setWindowTitle("B"); 
    window->setWindowIcon(QIcon(":/Images/Images/Bouclier.png")); 
    window->setFixedSize(820, 440); 
    window->show(); 
} 

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); 
} 

#ifndef SECONDWINDOW_H 
#define SECONDWINDOW_H 

#include <QListWidgetItem> 
#include <QWidget> 
#include <QString> 
#include <QIcon> 
#include "thirdwindow.h" 
#include "ui_thirdwindow.h" 

namespace Ui { 
class SecondWindow; 
} 

class SecondWindow : public QWidget 
{ 
    Q_OBJECT 

public: 
    explicit SecondWindow(QWidget *parent = 0); 
    ~SecondWindow(); 

public slots: 
    void ShowThirdWindow(); 
    void UpForLeft(); 
    void DownForLeft(); 
    void UpForRight(); 
    void DownForRight(); 
    void AddForLeft(); 
    void DeleteForLeft(); 
    void EditForLeft(QListWidgetItem *item); 

private: 
    Ui::SecondWindow *ui; 
    ThirdWindow *window; 
}; 

#endif // SECONDWINDOW_H 

도움을 주셔서 감사합니다. QListWidget

+0

무엇이 작동하지 않습니까? 당신이 얻는 오류는 무엇이며 무엇을 기대합니까? – Hayt

답변

0

은 볼 수있는 모델을 혼합하는 편리한 위젯입니다. 이렇게하면 트리 구조 데이터를 나타내는 최상위 모델의 데이터로 모델을 계속 보충해야하기 때문에 필요한 것보다 약간 어려워집니다.

대신, QStandardItemModel을 사용하고, QListView을 통해 노출 될 수 있습니다. 보기에는 트리가없는 특정 수준의 열 하나만이 표시됩니다. 하위 항목을 보려면 적절한 루트 색인을 선택하십시오.

QStandardItemModel의 키 누락 기능은 항목을 위/아래로 이동하는 데 필요한 moveRows입니다. 동일한 부모 내에서 단일 항목을 이동하는 것을 지원하는 제한된 구현으로 쉽게 해결할 수 있습니다. 따라서보기는 moveRow을 사용하여 완전히 모델에 의존하지 않을 수 있습니다. 우리는 moveRows 첫 번째 구현한다

// https://github.com/KubaO/stackoverflown/tree/master/questions/list-widgets-40403640 
#include <QtWidgets> 

class StandardItemModel : public QStandardItemModel { 
    bool moveRows(const QModelIndex &srcParent, int srcRow, int count, 
       const QModelIndex &dstParent, int dstRow) override { 
     if (count == 0) return true; 
     if (count != 1 || srcParent != dstParent) return false; 
     if (srcRow == dstRow) return true; 
     if (abs(srcRow - dstRow) != 1) return false; 
     auto root = srcParent.isValid() ? itemFromIndex(srcParent) : invisibleRootItem(); 
     if (!root) return false; 
     auto srcItem = root->takeChild(srcRow); 
     auto dstItem = root->takeChild(dstRow); 
     if (!srcItem || !dstItem) return false; 
     root->setChild(srcRow, dstItem); 
     root->setChild(dstRow, srcItem); 
     return true; 
    } 
public: 
    using QStandardItemModel::QStandardItemModel; 
}; 

는 계속해서, ListUi 위젯은 모델이 작동하는 방법에 대한 지식없이보기를 구현합니다. 이 예제의 경우 별도의 컨트롤을 사용하는 대신 새 항목이 제자리에서 편집됩니다. StandardItemModel

The appearance of ListUi widget.

class ListUi : public QWidget { 
    Q_OBJECT 
    QGridLayout m_layout{this}; 
    QVBoxLayout m_column; 
    QPushButton m_up{"⬆"}, m_down{"⬇"}, m_remove{"−"}, m_add{"+"}; 
    QLabel m_caption; 
    QListView m_list; 
    inline QAbstractItemModel * model() const { return m_list.model(); } 
    inline QModelIndex root() const { return m_list.rootIndex(); } 
    inline QModelIndex index(int row) const { return model()->index(row, 0, root()); } 
public: 
    ListUi(const QString & caption, QWidget * parent = nullptr) : 
     QWidget{parent}, 
     m_caption{caption} 
    { 
     m_layout.addWidget(&m_up, 0, 0); 
     m_layout.addWidget(&m_down, 1, 0, 1, 1, Qt::AlignTop); 
     m_layout.addLayout(&m_column, 0, 1, 3, 1); 
     m_column.addWidget(&m_caption); 
     m_column.addWidget(&m_list); 
     m_layout.addWidget(&m_remove, 0, 2); 
     m_layout.addWidget(&m_add, 2, 2); 
     m_caption.setAlignment(Qt::AlignCenter); 
     connect(&m_add, &QPushButton::clicked, [this]{ 
     int row = model()->rowCount(root()); 
     if (model()->columnCount(root()) == 0) 
      model()->insertColumn(0, root()); 
     if (model()->insertRow(row, root())) { 
      m_list.setCurrentIndex(index(row)); 
      m_list.edit(index(row)); 
     } 
     }); 
     connect(&m_remove, &QPushButton::clicked, [this]{ 
     if (m_list.currentIndex().isValid()) 
      model()->removeRow(m_list.currentIndex().row(), root()); 
     }); 
     connect(&m_up, &QPushButton::clicked, [this]{ 
     auto row = m_list.currentIndex().row(); 
     if (row > 0 && model()->moveRow(root(), row, root(), row - 1)) 
      m_list.setCurrentIndex(index(row-1)); 
     }); 
     connect(&m_down, &QPushButton::clicked, [this]{ 
     auto row = m_list.currentIndex().row(); 
     if (row >= 0 && row < (model()->rowCount(root()) - 1) && 
      model()->moveRow(root(), row, root(), row + 1)) 
      m_list.setCurrentIndex(index(row+1)); 
     }); 
    } 
    void setModel(QAbstractItemModel * model) { 
     m_list.setModel(model); 
     connect(m_list.selectionModel(), &QItemSelectionModel::currentChanged, this, &ListUi::currentIndexChanged); 
    } 
    void setRootIndex(const QModelIndex & index) { 
     m_list.setRootIndex(index); 
    } 
    Q_SIGNAL void currentIndexChanged(const QModelIndex &); 
}; 

간단한 테스트 하니스 두 ListUi의 인스턴스화

는하는 JSON 소스로부터 모델을 채우고, 원하는 기능을 얻기 위해 이들을 연결한다.

class Window : public QWidget { 
    Q_OBJECT 
    QGridLayout m_layout{this}; 
    ListUi m_programs{"Liste des programmes"}; 
    ListUi m_sessions{"Liste des sessions"}; 
    QPushButton m_generate{"Générer les données"}; 
    StandardItemModel m_model; 
public: 
    explicit Window(QWidget * parent = nullptr) : QWidget{parent} 
    { 
     m_layout.addWidget(&m_programs, 0, 0); 
     m_layout.addWidget(&m_sessions, 0, 1); 
     m_layout.addWidget(&m_generate, 1, 1, 1, 1, Qt::AlignRight); 
     m_programs.setModel(&m_model); 
     m_sessions.setModel(&m_model); 
     m_sessions.setDisabled(true); 
     connect(&m_programs, &ListUi::currentIndexChanged, [this](const QModelIndex & root){ 
     m_sessions.setEnabled(true); 
     m_sessions.setRootIndex(root); 
     }); 
     connect(&m_generate, &QPushButton::clicked, this, &Window::generateData); 
    } 
    Q_SIGNAL void generateData(); 
    void setJson(const QJsonDocument & doc) { 
     m_model.clear(); 
     auto object = doc.object(); 
     for (auto it = object.begin(); it != object.end(); ++it) { 
     if (!m_model.columnCount()) m_model.appendColumn({}); 
     auto root = new QStandardItem(it.key()); 
     m_model.appendRow(root); 
     if (it.value().isArray()) { 
      auto array = it.value().toArray(); 
      for (auto const & value : array) { 
       if (!root->columnCount()) root->appendColumn({}); 
       root->appendRow(new QStandardItem{value.toString()}); 
      } 
     } 
     } 
    } 
}; 

int main(int argc, char ** argv) { 
    QApplication app{argc, argv}; 
    auto json = R"--({ 
       "Foo":["Foo-1", "Foo-2", "Foo-3"], 
       "Bar":["Bar-1", "Bar-2"] 
       })--"; 
    Window ui; 
    ui.connect(&ui, &Window::generateData, [&]{ ui.setJson(QJsonDocument::fromJson(json)); }); 
    ui.show(); 
    return app.exec(); 
} 

#include "main.moc" 

표준 항목 모델을 반복하여 JSON 표현을 재생성하는 것은 간단합니다.

는 예를 마칩니다.