Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

QObject::connect problem with argument list



  • I'm to get the name of a file from the user's selection from a QFileSystemModel using a QTreeView. I get a compile error saying it couldn't convert the argument list when I do this

    @QString localFileName = "";
    QObject::connect(button, SIGNAL(clicked()), &localFileName, SLOT(append((model->data(tree->currentIndex(), Qt::DisplayRole)).toString())));@

    I know the last argument is messy, but its what I thought would work to get the file name only when the user clicks the button



  • In the slot you cannot have more arguments than the signal you're connecting with.
    Furthermore you should only put types in there, not variables.



  • you could try :

    @
    private:
    QString filename;
    @

    @
    myClass::myClass () {
    connect(button, SIGNAL(clicked()), this, SLOT(appendFilename()));
    }

    myClass::appendFilename() {
    filename = model->data(tree->currentIndex(), Qt::DisplayRole).toString();
    }
    @



  • It's a sad thing that you can't connect a 0-argument signal with a non-0-argument slot with some specified in connect parameters, but it's true. So the only way to do that is to create a 0-argument slot and 1-argument signal, and connect them like clicked()->newSlot(), newSignal(arg)->append(arg), where the newSignal is emmited from newSlot.



  • Well, many cases can be served by using QSignalMapper, and otherwise you can wait for Qt 5 that will support using a lambda function instead.



  • Oh, didn't know that! QSignalMapper appears to be perfect for this case.



  • It looks really useful, but I'm hoping to see if I can get this code to work before I erase all of it. The only problem now is a runtime error that says this in the command window:

    QObject::connect: No such slot QWidget::appendFileName()

    I do have appendFileName() declared a public slot and i have written the code that I want for the function itself



  • Does anyone know why I'm getting that error?



  • Code please. I have a guess, but code first



  • Public Declarations:
    @QFileSystemModel model;
    QTreeView tree;
    QString file;@

    The subroutine:
    @void MyWidget::appendFileName()
    {
    file.append((model.data(tree.currentIndex(), Qt::DisplayRole)).toString());
    fileAttained = true;
    }@

    In the main:
    @
    model.setRootPath(QDir::currentPath());
    tree.setModel(&model);
    QWidget *wid = new QWidget;
    button.setText("Select File");

    layout.addWidget(&tree);
    layout.addWidget(&button);

    wid->setLayout(&layout);
    wid->setFixedSize(1100, 500);
    wid->show();

    QObject::connect(&button, SIGNAL(clicked()), this, SLOT(appendFileName()));@



  • I don't get it. So you define a class MyWidget, then instantiate just simple Widget object and after all use this pointer in main(). Altogether this makes no sense.



  • that's my mistake, the main has a function call @widget.getFile();@ which is here:
    @void MyWidget::getFile()
    {
    model.setRootPath(QDir::currentPath());
    tree.setModel(&model);
    tree.setColumnWidth(0, 500);
    tree.resize(1000, 300);
    QWidget *wid = new QWidget;
    button.setText("Select File");

    layout.addWidget(&tree);
    layout.addWidget(&button);

    wid->setLayout(&layout);
    wid->setFixedSize(1100, 500);
    wid->show();

    QObject::connect(&button, SIGNAL(clicked()), this, SLOT(appendFileName()));

    }@

    Maybe this makes a bit more sense, I appreciate you helping. What was your guess?



  • Did you declare appendFileName() as a slot in your class header?

    @
    class MyWidget {
    // ....

    protected slots:
    void appendFileName();

    };
    @



  • yes sir I did



  • Then show us the complete code, please.



  • @#include <QtGui>
    #include <fstream>
    #include <iostream>

    using namespace std;

    class MyWidget : public QWidget
    {

    public:
    MyWidget();
    float currX1, currX2, currY1, currY2, nextX1, nextX2, nextY1, nextY2;
    float points[105][105];
    QString file;
    int numCols;
    int numRows;
    QFileSystemModel model;
    QTreeView tree;
    QVBoxLayout layout;
    QPushButton button;
    bool fileAttained;
    void getFile();

    protected slots:
    void appendFileName();

    protected:
    void paintEvent(QPaintEvent *);

    };

    MyWidget::MyWidget()
    {
    QPalette palette(MyWidget::palette());
    palette.setColor(backgroundRole(), Qt::white);
    setPalette(palette);

    }

    void MyWidget::paintEvent(QPaintEvent *)
    {
    // omitted
    }
    void MyWidget::appendFileName()
    {
    file.append((model.data(tree.currentIndex(), Qt::DisplayRole)).toString());
    fileAttained = true;
    }
    void MyWidget::getFile()
    {
    model.setRootPath(QDir::currentPath());
    tree.setModel(&model);
    tree.setColumnWidth(0, 500);
    tree.resize(1000, 300);
    QWidget *wid = new QWidget;
    button.setText("Select File");

    layout.addWidget(&tree);
    layout.addWidget(&button);

    wid->setLayout(&layout);
    wid->setFixedSize(1100, 500);
    wid->show();

    QObject::connect(&button, SIGNAL(clicked()), this, SLOT(appendFileName()));
    QObject::connect(&button, SIGNAL(clicked()), wid, SLOT(close()));

    }
    int main(int argc, char *argv[])
    {
    QApplication app(argc, argv);
    MyWidget widget;
    widget.getFile();

        // omitted 
    

    return app.exec();
    }
    @

    I have code commented out/ omitted from the post that does the second part of the program which is what relies on getting the name of the file that the user chooses



  • You missed the Q_OBJECT macro in your header file opf MyWidget:

    @
    class MyWidget : public QWidget
    {
    // this is missing
    Q_OBJECT;
    public:
    MyWidget();
    float currX1, currX2, currY1, currY2, nextX1, nextX2, nextY1, nextY2;
    float points[105][105];

    protected slots:
    void appendFileName();

    protected:
    void paintEvent(QPaintEvent *);
    };
    @



  • thank you, I had tried that and gotten errors so I thought it was wrong. so i tried again, got link errors, and I included "main.moc". Now there aren't link errors, but a the moc file has errors that I don't know how to fix. There are about 10 of them, heres the first to give you an example
    @1>.\GeneratedFiles\Release\main.moc(42) : error C2653: 'MyWidget' : is not a class or namespace name@

    I can copy the moc file too if you need it



  • Looks like you didn't include mywidget.h in your main.



  • Split up the class definition into a header file, and don't put definition and implemenation together in the cpp file.
    then it should work.

    Or include main.moc at the end of the file.


Log in to reply