2017-08-25 474 views
0

我在的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(),其中我试图再次插入按钮,在最后一栏。我的想法是,可能行数正在发生变化,所以我正在重新实施相同的逻辑。但是,它不起作用。

可以纠正我的逻辑或者其他逻辑来实现这一功能的人的帮助。提前致谢!

回答

0

您应该使用delegate该列。这样,视图自动处理行的创建/删除。见this question


也有一些其他的问题与您的代码:

  1. rowsInserted/rowsRemoved多次
  2. 连接在你的代码,你映射同类创建多个信号映射器连接。这不是它的intendend使用
  3. 复制的onRowsNumberChanged
+0

我之前使用委托,但它所产生的标准样式按钮,需要的样式。我尝试了两天,但不能适应风格。采用这种方法,除了处理自动创建/删除行之外,我能够实现最大的功能。你能帮我修改这个方法吗?非常感谢您的时间。 – tanmayb

+0

还有多个条目只是因为我试图找出正确的位置。另外,如果你能帮忙。 – tanmayb

+0

正如链接问题(以及qtcenter的后续链接)所述,使用小部件并不能很好地扩展。你应该真的使用一个委托。我建议你发布一个新的问题与委派方法 –

0

来解决使用小工具你的问题,你可以用下面的办法。它使用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); 
     }); 
    } 
}