2017-08-25 466 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); 
     }); 
    } 
}