信号/槽而在QTableView中模型插入和删除行动态
问题描述:
我在的tableview的最后一列插入一个QPushButton。使用该按钮,我使用按钮释放信号和插槽'handlebutton(int)'删除特定行。信号/槽而在QTableView中模型插入和删除行动态
CPP代码:
MainWindow::MainWindow(QWidget *parent) :
QDialog(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
QSortFilterProxyModel *model = new QSortFilterProxyModel(this);
model = pCApp->guiClient()->getConnectionManagement()->getProxyModel();
ui->tableView->setModel(model);
connect(pCApp, SIGNAL(CloseOpenWindowsRequested()), SLOT(close()));
connect(ui->tableView->model(), SIGNAL(rowsInserted(QModelIndex,int,int)), this, SLOT(onRowsNumberChanged()));
connect(ui->tableView->model(), SIGNAL(rowsRemoved(QModelIndex,int,int)), this, SLOT(onRowsNumberChanged()));
ui->tableView->setSortingEnabled(true);
QPushButton *button;
QSignalMapper *mapper = new QSignalMapper(this);
QObject::connect(mapper, SIGNAL (mapped(int)), this, SLOT (handleButton(int)));
for (int i = 0; i < model->rowCount(); i++)
{
button = new QPushButton;
button->setText("Disconnect " + QString::number(i));
button->setStyleSheet("QPushButton { color: #E5E5E5; }");
ui->tableView->setIndexWidget(model->index(i,2, QModelIndex()), button);
QObject::connect(button, SIGNAL(released()), mapper, SLOT(map()));
connect(ui->tableView->model(), SIGNAL(rowsInserted(QModelIndex,int,int)), this, SLOT(onRowsNumberChanged()));
connect(ui->tableView->model(), SIGNAL(rowsRemoved(QModelIndex,int,int)), this, SLOT(onRowsNumberChanged()));
mapper->setMapping(button, i);
}
setAttribute(Qt::WA_DeleteOnClose);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::handleButton(int row)
{
this->ui->tableView->model()->removeRow(row);
}
void MainWindow::onRowsNumberChanged()
{
QSortFilterProxyModel *model = new QSortFilterProxyModel(this);
model = pCApp->guiClient()->getConnectionManagement()->getProxyModel();
ui->tableView->setModel(model);
ui->tableView->setSortingEnabled(true);
QPushButton *button;
QSignalMapper *mapper = new QSignalMapper(this);
QObject::connect(mapper, SIGNAL (mapped(int)), this, SLOT (handleButton(int)));
for (int i = 0; i < model->rowCount(); i++)
{
button = new QPushButton;
button->setText("Disconnect " + QString::number(i));
button->setStyleSheet("QPushButton { color: #E5E5E5; }");
ui->tableView->setIndexWidget(model->index(i,2, QModelIndex()), button);
QObject::connect(button, SIGNAL(released()), mapper, SLOT(map()));
mapper->setMapping(button, i);
}
}
HPP代码:
#ifndef MAINWINDOW_HPP
#define MAINWINDOW_HPP
namespace Ui {
class MainWindow;
}
class MainWindow : public QDialog
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
public slots:
void onLanguageChanged();
void handleButton(int row);
void onRowsNumberChanged();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_HPP
在正常情况下,代码运行正常。但是,插入新行和/或删除旧行时,按钮不会根据需要显示在最后一列中。我试图用的信号 -
connect(ui->tvServStat->model(), SIGNAL(rowsInserted(QModelIndex,int,int)), this, SLOT(onRowsNumberChanged()));
connect(ui->tvServStat->model(), SIGNAL(rowsRemoved(QModelIndex,int,int)), this, SLOT(onRowsNumberChanged()));
插槽两个,我保持相同onRowsNumberChanged(),其中我试图再次插入按钮,在最后一栏。我的想法是,可能行数正在发生变化,所以我正在重新实施相同的逻辑。但是,它不起作用。
可以纠正我的逻辑或者其他逻辑来实现这一功能的人的帮助。提前致谢!
答
您应该使用delegate该列。这样,视图自动处理行的创建/删除。见this question
也有一些其他的问题与您的代码:
- 您
rowsInserted
/rowsRemoved
多次 - 连接在你的代码,你映射同类创建多个信号映射器连接。这不是它的intendend使用
- 复制的
onRowsNumberChanged
环
答
来解决使用小工具你的问题,你可以用下面的办法。它使用Qt 5的新连接的语法和C++ lambda表达式,从而可以消除信号映射器的需求:
#include "form.h"
#include <QtWidgets>
#include <QStandardItemModel>
Form::Form(QWidget *parent) :
QWidget(parent)
{
QPushButton *b = new QPushButton("add row");
m_tree = new QTreeView(this);
QBoxLayout *l = new QVBoxLayout(this);
l->addWidget(m_tree, 1);
l->addWidget(b);
QStandardItemModel *m = new QStandardItemModel(0, 3, this);
m_tree->setModel(m);
connect(b, &QPushButton::clicked, this, &Form::addRow);
connect(m, SIGNAL(rowsInserted(QModelIndex,int,int)), this, SLOT(addItemButtons()));
connect(m, SIGNAL(rowsRemoved(QModelIndex,int,int)), this, SLOT(addItemButtons()));
}
Form::~Form()
{
}
void Form::addRow()
{
m_tree->model()->insertRow(m_tree->model()->rowCount());
}
void Form::addItemButtons()
{
for (int i = 0; i < m_tree->model()->rowCount(); ++i) {
auto idx = m_tree->model()->index(i, 2);
QPushButton *b = new QPushButton("X");
b->setStyleSheet("QPushButton {color: #E5E5E5;}");
m_tree->setIndexWidget(idx, b);
connect(b, &QPushButton::clicked, [=](){
m_tree->model()->removeRow(i);
});
}
}
我之前使用委托,但它所产生的标准样式按钮,需要的样式。我尝试了两天,但不能适应风格。采用这种方法,除了处理自动创建/删除行之外,我能够实现最大的功能。你能帮我修改这个方法吗?非常感谢您的时间。 – tanmayb
还有多个条目只是因为我试图找出正确的位置。另外,如果你能帮忙。 – tanmayb
正如链接问题(以及qtcenter的后续链接)所述,使用小部件并不能很好地扩展。你应该真的使用一个委托。我建议你发布一个新的问题与委派方法 –