gpt4 book ai didi

c++ - 链接两个 QListWidget

转载 作者:太空宇宙 更新时间:2023-11-04 13:09:54 24 4
gpt4 key购买 nike

我想链接两个 QListWidget,但我不知道如何使用代码。这是我所做的: Help我们可以看到两个QListWidget。对于左侧的 QListWidget,我添加了(例如:“Bonjour”、“Hello”、“Tag”)三个 QListWidgetItem。我希望如果我单击左侧 QListWidget 的三个 QListWidgetItem 之一,我可以将 QListWidgetItem 添加到右侧 QListWidget (例如,对于“Bonjour”:“Tu”,“Vas”,“Bien”)。如果我不点击三个 QListWidgetItem 中的一个,我就无法添加 QListWidgetItem 与正确的 QListWidget。如果我为“Bonjour”做了:“Tu”、“Vas”、“Bien”,然后单击“Hello”(显然,“Hello”不包含任何内容),则正确的 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

谢谢你的帮助。

最佳答案

QListWidget 是一个将模型与 View 混合在一起的便捷小部件。这使事情变得比必要的更难一些,因为您需要使用代表树结构数据的顶级模型中的数据不断补充模型。

相反,您可以使用 QStandardItemModel,并通过 QListView 公开它。该 View 仅显示树的给定级别的一列,没有任何子项。要查看子项,请选择适当的根索引。

QStandardItemModel 缺少的一个关键功能是 moveRows,需要向上/向下移动项目。这很容易通过支持在同一父级中移动单个项目的有限实现来补救。因此,通过使用 moveRow, View 可以完全与模型无关。我们将首先实现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 小部件实现了该 View ,而无需了解模型如何工作。就此示例而言,新项目是就地编辑的,而不是使用单独的控件。

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,一个 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 表示是一件简单的事情。

示例到此结束。

关于c++ - 链接两个 QListWidget,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40403640/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com