0

I succeeded in adding a button in each row in TableView. However, I got stuck when I try to let them connect to other page.

I want to make a program that, when the button is clicked, another page will be opened.

The following code is my header file:

//list of blog.h
#ifndef LISTOFBLOGS_H
#define LISTOFBLOGS_H

#include <QJsonArray>
#include <QDialog>
#include <QFont>
#include <QSignalMapper>

namespace Ui {
class listofblogs;
}

class listofblogs : public QDialog
{
    Q_OBJECT

public:
    explicit listofblogs(QWidget *parent = nullptr);
    ~listofblogs();
    void setuserID(QString userID);
    QString getuserID();

private slots:
    void on_pushButton_clicked();
    void doSomething(int row);
    void map();

private:
    Ui::listofblogs *ui;
    QString UserID;
    QSignalMapper *signalMapper;
};
#endif // LISTOFBLOGS_H

Then, this is the C++ source code:

#include "listofblogs.h"
#include "ui_listofblogs.h"
#include "readandwritejson.h"
#include "blog.h"

void listofblogs::doSomething(int row){
    qDebug()<<row;
}

listofblogs::listofblogs(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::listofblogs)
{
    ui->setupUi(this);
    QFont font=ui->label_2->font();
    font.setPointSize(16);
    ui->label_2->setFont(font);
    QTableWidget *tw = ui->tableWidget;
    tw->clear();
    tw->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch);
    QStringList columns;
    columns << "title" << "userID" << "time"<< "open content";
    QJsonArray bloglist=readbloglist();
    int row = bloglist.size();
    int col = columns.size();
    tw->setRowCount(row);
    tw->setColumnCount(col);
    for (int i = 0; i < col; ++i){
             tw->setHorizontalHeaderItem(i, new QTableWidgetItem(columns.at(i)));
    }
    signalMapper = new QSignalMapper(this);
    for( int i=0; i<row; i++ ) {
        QJsonObject temp = bloglist.at(i).toObject();
        for (int j = 0; j < col-1; j++){

            auto item = tw->model()->index(i, j);
            QString col_data = columns.at(j);
            tw->model()->setData(item, QVariant::fromValue(temp.value("blogData").toObject().value(col_data).toString()));

        }
        //make new button for this row
        auto item = tw->model()->index(i, columns.size()-1);
        QPushButton *cartButton = new QPushButton("open");
        cartButton->setMaximumWidth(50);
        tw->setIndexWidget(item, cartButton);

        connect(cartButton, SIGNAL(clicked(bool)), this, SLOT(map()));
        //connect(cartButton, &QPushButton::clicked, signalMapper, &QSignalMapper::map);
        signalMapper->setMapping(cartButton, i);
    }
    connect(signalMapper, SIGNAL(mapped(int)), this, SLOT(doSomething(int)));
    for(int col = 0; col < columns.size(); col++) {
        tw->resizeColumnToContents(col);
    }
    tw->horizontalHeader()->setStretchLastSection(true);
    tw->setEditTriggers(QAbstractItemView::NoEditTriggers);
    tw->scrollToBottom();
    tw->verticalHeader()->hide();
    tw->setSelectionMode(QAbstractItemView::NoSelection);
    tw->resizeColumnsToContents();
}

listofblogs::~listofblogs()
{
    delete ui;
}
void listofblogs::setuserID(QString userID){
    UserID=userID;
}

QString listofblogs::getuserID(){
    return UserID;
}
void listofblogs::on_pushButton_clicked()
{
    blog *Blog;
    Blog = new blog(this);
    Blog->setuserID(UserID);
    Blog->show();
}

I can compile this code but, when I clicked a button, the error occurs because I didn't define the map() function, but how could I define it? (I made this program based on this Q&A.)

Also, when I changed this part from:

connect(signalMapper, SIGNAL(mapped(int)), this, SLOT(doSomething(int)));

to:

connect(signalMapper, &QSignalMapper::mappedString,
                this, &listofblogs::doSomething(row));

I got this error and could not compile it:

listofblogs.cpp:51:9: error: no matching member function for call to 'connect'
qobject.h:197:36: note: candidate function not viable: no known conversion from 'void (QAbstractButton::*)(bool)' to 'const char *' for 2nd argument
qobject.h:200:36: note: candidate function not viable: no known conversion from 'void (QAbstractButton::*)(bool)' to 'const QMetaMethod' for 2nd argument
qobject.h:443:41: note: candidate function not viable: no known conversion from 'void (QAbstractButton::*)(bool)' to 'const char *' for 2nd argument
qobject.h:217:43: note: candidate template ignored: couldn't infer template argument 'Func2'
qobject.h:258:13: note: candidate template ignored: couldn't infer template argument 'Func2'
qobject.h:297:13: note: candidate template ignored: couldn't infer template argument 'Func2'
qobject.h:249:13: note: candidate function template not viable: requires 3 arguments, but 4 were provided
qobject.h:289:13: note: candidate function template not viable: requires 3 arguments, but 4 were provided
Adrian Mole
  • 49,934
  • 160
  • 51
  • 83
  • 1
    &listofblogs::doSomething(row) - this is wrong. You have to pass the address of the function, not the return value of the function call -> &listofblogs::doSomething – chehrlic Apr 02 '22 at 16:38

1 Answers1

0

I recommend you to use the lower level QTableView along with QAbstractItemDelegate, however you can subclass QAbstractItemDelegate and integrate a button inside it, them map the button click signal to a slot, the selected page will either depend on the model's data or the index of the delegate

sadeq
  • 21
  • 1
  • 5