Qt: connect() requires at least 4 arguments, but 2 were provided - c++

What am I missing here, why is the following example giving me compile-time errors?
testline.h:
#include <QLineEdit>
class TestLine : public QLineEdit
{
Q_OBJECT
public:
TestLine(QWidget *parent = 0);
public slots:
virtual void on_textEdited(const QString&);
};
testline.cpp:
#include "testline.h"
TestLine::TestLine(QWidget *parent) : QLineEdit(parent)
{
connect(this, SIGNAL(textEdited(const QString &))), this,
SLOT(on_textEdited(const QString &)));
}
void TestLine::on_textEdited(const QString &text)
{
// something
}
error message:
../testline.cpp:7:5: error
: no matching member function for call to 'connect'
connect(this, SIGNAL(textEdited(const QString &))), this,
^~~~~~~
../../../Qt/5.7/clang_64/lib/QtCore.framework/Headers/qobject.h:219:43: note: candidate function template not viable: requires at least 4 arguments, but 2 were provided

connect(this, SIGNAL(textEdited(const QString &)))
// 1 2 3 321
At this point you are doing what exactly the compiler output says - you are calling connect() with only 2 parameters.

Related

Initialization of the constructor of a QThread C++ with QString parameter

is it possible to initialize a new QThread with a parameter?? I created two threads in MainWindow. Now i want initialize the Thread "mySave" with a QString. But it doesn't work.
void MainWindow::on_startButton_clicked()
{
thread = new QThread();
mThread = new myThread();
threadSave = new QThread();
mSave = new mySave("HelloWorld");
....
}
I change the line mSave = new mySave() to mySave = new mySave("HelloWorld") and the constructor of mySave-Class to
mySave::mySave(QObject *parent, QString stringFromMainWindow)
: QObject{parent}, m_string{stringFromMainWindow}
{
this->stringMySave = stringFromMainWindow;
}
mySave.h
class mySave : public QObject
{
Q_OBJECT
public:
explicit mySave(QObject *parent = nullptr, QString stringFileName = NULL);
private:
QFile file;
QString m_string {};
....
But i become a fault!
mainwindow.cpp:57:17: error: no matching constructor for initialization of 'mySave'
mysave.h:9:7: note: candidate constructor (the implicit copy constructor) not viable: no known conversion from 'const char [6]' to 'const mySave' for 1st argument
mysave.h:13:14: note: candidate constructor not viable: no known conversion from 'const char [6]' to 'QObject *' for 1st argument
What's wrong...??
Without QString parameter everthing works fine:
void MainWindow::on_startButton_clicked()
{
thread = new QThread();
mThread = new myThread();
threadSave = new QThread();
mSave = new mySave();
connect(thread, SIGNAL(finished()), mThread, SLOT(deleteLater()));
connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
connect(mThread, SIGNAL(emitData(const QByteArray &)), this, SLOT(setEditText(const QByteArray &)));
mThread->moveToThread(thread);
thread->start();
mSave->moveToThread(threadSave);
threadSave->start();
QMetaObject::invokeMethod(mThread, "interfaceSerial");
QMetaObject::invokeMethod(mSave, "startFile", Q_ARG(QString, fileName));
qDebug() << "Main open " << QThread::currentThread();
dataTimer.start(0); // Interval 0 means to refresh as fast as possible
}
mySave-Thread constructor
mySave::mySave(QObject *parent)
: QObject{parent}
{
qDebug() << "Thread open " << QThread::currentThread();
}
How can i set a QString parameter in the constructor of a new QThread....??
Thanks & Bye bye
The problem was solved...you have to write
class mySave : public QObject
{
Q_OBJECT
public:
explicit mySave(QString stringFileName = NULL, QObject *parent = nullptr);
private:
QFile file;
The last parameter has to be the QObject!!
Look at your mySave constructor signature...
explicit mySave(QObject *parent = nullptr, QString stringFileName = NULL);
The first parameter passed must be a QObject * (or something implicitly convertible to a QObject *) and the second parameter passed must be a QString. If you want mySave to be constructible using a QString only then you must provide a suitable constructor. The obvious option would be to simply reverse the order of the passed parameters...
explicit mySave(QString stringFileName = QString(), QObject *parent = nullptr);
Having said that, the most commonly used constructor calls for classes of this nature would probably be...
/* Default constructor: no text or parent. */
mySave ms1;
/* Text only. */
mySave ms2("Some text...");
/* Parent object only. */
QObject *parent = ...;
mySave ms3(parent);
/* Pass both text and parent object. */
mySave ms4("Some text...", parent);
All of these cases can be provided by the following two constructors...
mySave::mySave (const QString &stringFileName = QString(), QObject *parent = nullptr)
: QObject(parent)
, m_string(stringFileName)
{
...
}
mySave::mySave (QObject *parent)
: QObject(parent)
{
...
}
Or, if you prefer, make the second a delegating constructor...
mySave::mySave (QObject *parent)
: mySave(QString(), parent)
{}

C++ Reference to non-static member function is required

I am making a simple browser using QT5.
I have a QMainWindow with a QWebEngineView inside of it and I am trying to make it so that it auto accepts permission requests but I can't seem to get it to work... (Later I will make it prompt the user)
I looked online and found something but the solution didn't work for me as they set their application up differently than I did.
The main.cpp is simply the default with a declaration of MainWindow and showing it
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QUrl>
#include <QWebEngineView>
#include <QWebEnginePage>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
connect(ui->view->page(), ui->view->page()->featurePermissionRequested, this, this->onFeaturePermissionRequested);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_lineEdit_returnPressed()
{
QString url = ui->lineEdit->text();
QUrl curl;
curl.setUrl(url);
ui->view->setUrl(curl);
}
void MainWindow::on_back_pressed()
{
ui->view->back();
}
void MainWindow::on_forward_pressed()
{
ui->view->forward();
}
void MainWindow::on_reload_pressed()
{
ui->view->reload();
}
void MainWindow::on_view_urlChanged(const QUrl &arg1)
{
QString newurl = arg1.toString();
QStringList urllist = newurl.split('?');
ui->lineEdit->setCursorPosition(0);
ui->lineEdit->setText(urllist[0]);
}
void MainWindow::onFeaturePermissionRequested(const QUrl &securityOrigin, QWebEnginePage::Feature feature)
{
ui->view->page()->setFeaturePermission(securityOrigin, feature, QWebEnginePage::PermissionPolicy(1));
}
And the header file is as so:
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QWebEnginePage>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void on_lineEdit_returnPressed();
void on_back_pressed();
void on_forward_pressed();
void on_reload_pressed();
void on_view_urlChanged(const QUrl &arg1);
void onFeaturePermissionRequested(const QUrl &securityOrigin, QWebEnginePage::Feature feature);
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
Whenever I attempt to build it I get these messages
/home/kiwifruit555/Documents/kUwU/Web/mainwindow.cpp:12: error: invalid use of non-static member function ‘void QWebEnginePage::featurePermissionRequested(const QUrl&, QWebEnginePage::Feature)’
../Web/mainwindow.cpp: In constructor ‘MainWindow::MainWindow(QWidget*)’:
../Web/mainwindow.cpp:12:49: error: invalid use of non-static member function ‘void QWebEnginePage::featurePermissionRequested(const QUrl&, QWebEnginePage::Feature)’
12 | connect(ui->view->page(), ui->view->page()->featurePermissionRequested, this, this->onFeaturePermissionRequested);
| ~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~
/usr/include/qt/QtWebEngineWidgets/QWebEnginePage:1: In file included from /usr/include/qt/QtWebEngineWidgets/QWebEnginePage:1,
In file included from /usr/include/qt/QtWebEngineWidgets/QWebEnginePage:1,
from ../Web/mainwindow.h:5,
from ../Web/mainwindow.cpp:1:
/usr/include/qt/QtWebEngineWidgets/qwebenginepage.h:342:10: note: declared here
342 | void featurePermissionRequested(const QUrl &securityOrigin, QWebEnginePage::Feature feature);
| ^~~~~~~~~~~~~~~~~~~~~~~~~~
I have tried multiple things but I cannot seem to get it to work...
The connection syntax should be:
connect(ui->view->page(), &QWebEnginePage::featurePermissionRequested, this, &MainWindow::onFeaturePermissionRequested);
Fore more information read New Signal Slot Syntax.
It is also better to use the enum value explicitly instead of the numeric value:
ui->view->page()->setFeaturePermission(securityOrigin, feature, QWebEnginePage::PermissionGrantedByUser);

Disconnecting signals fails

In my code I want to reroute a signal-slot-connection, i.e. first the slot is connected to signal 1, and after the rerouting it should only be connected to signal 2. For that I used disconnect(this), with this referring to the class which owns the slots (it is in a class function). This command should disconnect all signals from extern from the class. Unfortunately, I get false as return value of disconnect(). Why can't I disconnect the signals? Is there a possibility to get more information?
Strangely, in my example below the disconnect and reconnect does not work, too, I get the same error code from disconnect.
If I remove the line connect(this, &MainWindow::writeLine, class1, &TXClass::emit_signal); from the on_PushButton2_clicked()-function, disconnect() still returns "false", but I get the expected result.
Example code:
Mainwindow.cpp:
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
class1 = new TXClass("Class 1");
class2 = new TXClass("Class 2");
connect(this, SIGNAL(writeLine()), class1, SLOT(emit_signal()));
connect(class1, SIGNAL(signal(QString)), this, SLOT(newText(QString)));
}
MainWindow::~MainWindow()
{
delete class1;
delete class2;
delete ui;
}
void MainWindow::newText(QString text)
{
ui->lineEdit->setText(text);
}
void MainWindow::on_pushButton_clicked()
{
emit writeLine();
}
void MainWindow::on_pushButton_2_clicked()
{
qDebug() << "Disconnect result: " << disconnect(this);
connect(this, &MainWindow::writeLine, class2, &TXClass::emit_signal);
connect(this, &MainWindow::writeLine, class1, &TXClass::emit_signal);
connect(class2, &TXClass::signal, this, &MainWindow::newText);
//The onliest signal I want to get now is from class2.
}
MainWindow.h:
#include <QDebug>
#include <txclass.h>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
signals:
void writeLine(void);
public slots:
void on_pushButton_clicked();
void newText(QString text);
void on_pushButton_2_clicked();
private:
Ui::MainWindow *ui;
TXClass *class1, *class2;
};
#endif // MAINWINDOW_H
TXClass.cpp:
#include "txclass.h"
TXClass::TXClass(QString name)
{
TXClass::name = name;
}
void TXClass::emit_signal()
{
emit signal(name);
}
TXClass.h:
#ifndef TXCLASS_H
#define TXCLASS_H
#include <QObject>
class TXClass : public QObject
{
Q_OBJECT
private:
QString name;
signals:
void signal(QString string);
public slots:
void emit_signal(void);
public:
TXClass(QString name);
};
#endif // TXCLASS_H
I've checked how QObject::disconnect is implemented and I don't see how this is supposed to work if you only specify receiver. QMetaObjectPrivate::disconnect will return immediately with false when sender is not specified. This means that second part of QObject::disconnect will no set res to true. The only other place you could get true out of is call to QInternal::activateCallbacks. But it doesn't look like it's instance specific, rather some global stuff (I admit I have no idea what exactly is this suppose to do :/).
I solution that works and seems good enough is this:
void MainWindow::second()
{
qDebug() << "Disconnect result: " << class1->disconnect();
connect(this, &MainWindow::writeLine, class2, &TXClass::emit_signal);
connect(this, &MainWindow::writeLine, class1, &TXClass::emit_signal);
connect(class2, &TXClass::signal, this, &MainWindow::newText);
//The onliest signal I want to get now is from class2.
}

How to subclass in Qt?

I'd like to subclass QListWidgetItem, but I don't get what I'm doing wrong.
I subclassed QListWidget without any trouble using the same principles.
This is my header file :
#ifndef LSPROLISTITEM_H
#define LSPROLISTITEM_H
#include <QObject>
#include <QListWidgetItem>
class LsproListItem : public QListWidgetItem
{
Q_OBJECT
public:
explicit LsproListItem(QString &text, QObject *parent = 0);
signals:
public slots:
};
#endif // LSPROLISTITEM_H
and this is my cpp file :
#include "lsprolistitem.h"
#include <QListWidgetItem>
LsproListItem::LsproListItem(QString & text, QObject *parent) :
QListWidgetItem(text, parent)
{
}
I don't get the argument from my custom constructor, to create an object based on QListWidgetItem..
I try to create is this way :
LsproListItem *simpleText = new LsproListItem("Lorem ipsum");
But this fails with :
appcms.cpp: error : no matching constructor for initialization of 'LsproListItem'
LsproListItem *simpleText = new LsproListItem("Lorem ipsum");
^ ~~~~~~~~~~~~~
lsprolistitem.h:7: candidate constructor (the implicit copy constructor) not viable: no known conversion from 'const char [12]' to 'const LsproListItem' for 1st argument
class LsproListItem : public QListWidgetItem
^
lsprolistitem.h:: candidate constructor not viable: no known conversion from 'const char [12]' to 'QString &' for 1st argument
explicit LsproListItem(QString &text, QObject *parent = 0);
^
Quick solution(not the best): don't use reference:
public:
explicit LsproListItem(QString text, QObject *parent = 0);
//...
LsproListItem::LsproListItem(QString text, QObject *parent) :
Or
public:
explicit LsproListItem( const QString &text, QObject *parent = 0);
//...
LsproListItem::LsproListItem( const QString &text, QObject *parent) :
But there is another mistake. Remove Q_OBJECT macro because QListWidgetItem is not a QObject subclass and you can't use here signal and slots.
To prove: http://qt-project.org/doc/qt-5/qlistwidgetitem.html

QT Connection between classes

I think i have some troubles getting this right: I have a QMainWindow class. In my programm I want to create other classes e.g. for input handling, computation...
Now first from my mainwindow class i want to send to my fileselector (file handler) class to open a file dialog, thus save the selected files internally. Unfortunately I am having troubles to connect the slots.
main window:
MA_FEX::MA_FEX(QWidget *parent)
: QMainWindow(parent), fileSelector(this)
{
ui.setupUi(this);
//this works:
fileSelector.openFiles(this);
//this doesn't:
connect(ui.actionOpenFiles, SIGNAL(triggered()), fileSelector, SLOT(openFiles(this)));
}
MA_FEX::~MA_FEX()
{
}
mainwindow header:
class MA_FEX : public QMainWindow
{
Q_OBJECT
public:
MA_FEX(QWidget *parent = 0);
~MA_FEX();
private:
Ui::MA_FEXClass ui;
FileSelection fileSelector;
};
file coordination class:
FileSelection::FileSelection(QObject *parent)
: QObject(parent)
{
}
FileSelection::~FileSelection()
{
}
void FileSelection::openFiles(QWidget *parent){
QStringList files = QFileDialog::getOpenFileNames(
parent,
"Select one or more files to open",
"c:",
"Images (*.csv *.txt )");
}
header:
class FileSelection : public QObject
{
Q_OBJECT
public:
FileSelection(QObject *parent);
~FileSelection();
public slots:
void openFiles(QWidget *parent);
private:
};
Am I missing something ? Executing i get Error C2664 on the connect line saying that Parameter 3 'FileSelection' cannot be converted to 'const QObject'.
Look at the declaration of the QObject::connect:
QObject::connect(const QObject * sender, const char * signal,
const QObject * receiver, const char * method,
Qt::ConnectionType type = Qt::AutoConnection);
It takes pointers, so you need to pass a pointer to fileSelector.
Another problem there is incompatible SIGNAL and SLOT. The slot specification in connect is declaration, so you cannot pass arguments as you did with this. If you use Qt 5 and C++11 you can do that by passing lambda instead of slot specification:
QObject::connect(ui.actionOpenFiles, &QAction::triggered,
[this]() { fileSelector.openFiles(this); });
For Qt 4 you need to create wrapping slot in your MA_FEX class which takes no arguments and which will invoke the slot of the fileSelector:
class MA_FEX {
...
Q_SLOT void openFileSelector() { fileSelector.openFiles(this); }
...
public:
MA_FEX(QWidget *parent) : QMainWindow(parent), fileSelector(this) {
ui.setupUi(this);
connect(ui.actionOpenFiles, SIGNAL(triggered()), SLOT(openFileSelector()));
}
...
};