2016-11-03 83 views
1

我想鏈接兩個QListWidget,但我不知道如何處理代碼。這裏是我做的: Help 我們可以看到兩個QListWidget。用左邊的QListWidget,我添加(例如:「Bonjour」,「Hello」,「Tag」)三個QListWidgetItem。我想,如果我點擊左QListWidget的三個QListWidgetItem中的一個,我可以用正確的QListWidget(例如,「Bonjour」:「Tu」,「Vas」,「Bien」)添加QListWidgetItem。如果我沒有點擊三個QListWidgetItem中的一個,我不能添加具有正確QListWidget的QListWidgetItem。如果我爲「Bonjour」做了:「Tu」,「Vas」,「Bien」,我點擊「Hello」(顯然,「Hello」不包含任何內容),右邊的QListWidget沒有任何內容。這只是我想要做的一個例子。下面,我寫我的代碼,如果它是有幫助的:鏈接兩個QListWidget

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

- secondwindow.h -

#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 

謝謝你的幫助。

+0

那裏不起作用?你得到的錯誤是什麼,你期望什麼。 – Hayt

回答

0

A QListWidget是一種將模型與視圖混合的便利小部件。這使得事情比需要更難一些,因爲您需要使用代表樹型結構數據的頂級模型中的數據來補充模型。

取而代之,您可以使用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控件實現視圖,沒有模型是如何發揮作用的任何知識。就本例而言,新項目在原地進行編輯,而不是使用單獨的控件。

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

一個簡單的測試工具實例2個ListUi S,A StandardItemModel,填充從一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表示是一件簡單的事情。

這就結束了這個例子。