Qt: having problems responding on QWebView::linkClicked(QUrl) - slot signal issue - c++

I am pretty new with Qt.
I want to respond to linkClicked in QWebView.
I tried connect like this:
QObject::connect(ui->webView, SIGNAL(linkClicked(QUrl)),
MainWindow,SLOT(linkClicked(QUrl)));
But I was getting error: C:/Documents and Settings/irfan/My Documents/browser1/mainwindow.cpp:9: error: expected primary-expression before ',' token
When I do this using UI Editing Signals Slots:
I have in header file declaration of slot:
void linkClicked(QUrl &url);
in source cpp file :
void MainWindow::linkClicked(QUrl &url)
{
QMessageBox b;
b.setText(url->toString());
b.exec();
}
When I run this it compiles and runs but got a warning :
Object::connect: No such slot MainWindow::linkClicked(QUrl)
in ui_mainwindow.h:100
What is proper way of doing this event handling?

You state that it now works because you changed QObject::connect to connect. Now I'm not 100% on this but I believe the reason for this is that by calling connect, you are calling the method associated with an object which is part of your application. i.e. it's like doing this->connect(...). That way, it is associated with an existing object - as opposed to calling the static method QObject::connect which doesn't know anything about your application.
Sorry if that's not clear, hopefully I got the point across!

Using QObject::connect() and connect() is same in this context. I believe
QObject::connect(ui->webView,SIGNAL(linkClicked(QUrl)),
MainWindow,SLOT(linkClicked(QUrl)));
was called from a function inside MainWindow class. That is why when you tried
connect(ui->webView,SIGNAL(linkClicked(const QUrl)),
this,SLOT(linkClicked(const QUrl)),Qt::DirectConnection);
it works. Notice the difference that make it work - the third parameter. You used this in the second snippet, where as you used MainWindow in the first snippet.
Read this to know how signals and slots mechanism works and how to properly implement it.

I changed QObject::connect to only connect and it works.
So this code works:
connect(ui->webView,SIGNAL(linkClicked(const QUrl)),this,SLOT(linkClicked(const QUrl)),Qt::DirectConnection);
But I don't know why?

Related

Qt 5.11, QWidget and creating a window and connecting to signals

I am dynamically creating new windows using:
QWidget* pobjWin = new QWidget();
pobjNode->setWidget(pobjWin);
pobjWin->resize(intWidth, intHeight);
pobjWin->move(intX, intY);
This works and in my application I have 3 windows, I want to connect to the various signals that according to the online documentation are:
activeChanged
contentOrientationChanged
focusObjectChanged
...
In my application as an example I connect to these signals with:
QObject::connect(pobjWin, SIGNAL(activeChanged(void))
,pobjSubNode
,SLOT(windowSlotActiveChanged(void)));
The pointer 'pobjSubNode' points to a class which has defined slots for each of the signals I am connecting to.
When I run this and the connects are executed I get:
2018-10-25 16:26:39.550030+0100 XMLMPAM[2048:219099] QObject::connect: No such signal QWidget::activeChanged(void) in ../XMLMPAM/clsMainWnd.cpp:733
I think the issue is because the pobjWin points to a QWidget and not a QWindow, but I couldn't find an example that doesn't create a window this way.
[Edit] Using the new connection method:
QObject::connect(pobjWin, &QWindow::activeChanged
,pobjSubNode, &clsXMLnode::windowSlotActiveChanged);
The prototypes for activeChanged and windowSlotActiveChanged are identical. But when I build with this implementation I get:
/Users/simonplatten/XMLMPAM/clsMainWnd.cpp:733: error: no matching function for call to 'connect'
QObject::connect(pobjWin, &QWindow::activeChanged
^~~~~~~~~~~~~~~~
[Edit2] I've changed the connect to:
QObject::connect(pobjWin->windowHandle(), &QWindow::activeChanged
,pobjSubNode, &clsXMLnode::windowSlotActiveChanged);
Now I get:
2018-10-25 17:37:22.299066+0100 XMLMPAM[2930:423194] QObject::connect: invalid null parameter
Having just assigned:
QWindow* pobjW2 = pobjWin->windowHandle();
I can see in the debugger that pobjW2 is NULL, which explains the error.
Changing the line:
QWidget* pobjWin = new QWidget();
To:
QWindow* pobjWin = new QWindow();
Has fixed the connection problems, once I fixed all the methods to use the QWindow versions instead of the QWidget versions, but now I don't get any visible windows...investigating. Its odd that the methods in QWindow have different names to those that do the exact same job in QWidget.
[Edit 3] After fixing the problems with help on correcting the connection and inserting a call to showNormal before creating the connections. The code is exactly as originally posted with a call to pobjWin->showNormal before any connects.
Fixed, I acknowledge the input from eylanesc, thank you.
I had to add a call to:
pobjWin->showNormal();
Before attempting the signal / slot connections, an example of a signal and slot connection now looks like:
QObject::connect(pobjWin->windowHandle(), &QWindow::activeChanged
,pobjSubNode, &clsXMLnode::windowSlotActiveChanged);

Qt connect doesn't recognize with lambda expression

I'm designed a QTableWidget with QPushButton, I would like to connect these buttons with a slot to hide some rows.
I'm using a lambda expression to pass a number of a row. But the compiler doesn't recognized this expression :
connect(this->ui->tableWidget->cellWidget(i,0),&QPushButton::clicked,[this,i]{hideRows(i);});
I have this error:
error: no matching function for call to 'SoftwareUdpater::MainWidget::connect(QWidget*, void (QAbstractButton::*)(bool), SoftwareUdpater::MainWidget::displayTable()::<lambda(int)>)'
The function hideRows(int) is declared as a function. And, as a slot, it doesn't work,
CONFIG += c++11 is added in pro file,
My class MainWidget inherits from QWidget,
Q_OBJECT is added in the header.
So I don't udnerstand why connect() is not recognized by Qt 5.9.1 MinGw 32bit.
Edit: [this,i]() instead of [this](const int i) for the lambda expression
Your connection is wrong. You can't connect a function that doesn't take parameters (clicked()) with a function that takes parameters (your lambda). To verify that this is the case, just do this:
connect(this->ui->tableWidget->cellWidget(i,0),&QPushButton::clicked,[this](){});
And see that it will compile. You have to make your design in such a way that signals and slots are compatible.
Also avoid using lambdas in signals and slots. Read the caveats here.
I was reading your comments on the accepted answer and noticed the root of the problem: This error is being thrown because the effective type of the object — as supplied to QObject::connect; i.e QWidget in your case — does not define the referenced signal QPushButton::clicked.
What likely happened is that the QPushButton pointer was cast into a QWidget and then that pointer was given to connect instead of the original which defines the signal.
Cast the pointer back to a QPushButton * and the error should go away.

Qt signal on buttongroup not connected

I have a buttongroup defined with two radiobuttons
buttonGroupFFTDimension = new QButtonGroup(this);
buttonGroupFFTDimension->addButton(ui->radioButton1D, 1);
buttonGroupFFTDimension->addButton(ui->radioButton2D, 2);
buttonGroupFFTDimension->setExclusive(true);
ui->radioButton1D->setChecked(true);
The connect also compiles
connect(this->buttonGroupFFTDimension, static_cast<void(QButtonGroup::*)(int)>(&QButtonGroup::buttonClicked),
this, &MainWindow::on_buttonGroupFFTDimension_buttonClicked);
but it throws and error at runtime
QMetaObject::connectSlotsByName: No matching signal for on_buttonGroupFFTDimension_buttonClicked(int)
I admit that I am not familiar with the new connect syntax, but also do not see the obvious error. What is wrong?
The message shown is because you are using Qt Designer and it uses the connectSlotsByName method to connect various elements, it recognizes the format on_somesender_somesignal, and in your case matches your slot.
First solution: It iss unnecessary to use the connect function, this will automatically do it. Also I think that the slot does not have as parameter the type int that requires.
In your case the slot should be as follows:
private slots:
void on_buttonGroupFFTDimension_buttonClicked (int val);
Another possible solution is to rename the slot, after that you run make clean and qmake.

I'm having trouble connecting a signal in my custom class to a slot in my main window

So, I've been working on my GUI and it's gotten pretty large, so I decided to split it into multiple widgets that communicate with the main window (probably something that I should have done from the beginning). I've partitioned part of my GUI into a separate widget, but I'm having trouble setting up signals and slots between the main window and the new widget, and I was hoping you could help me figure out what I'm doing wrong.
The main window is called robotmainwindow and the widget is called robotTabWidget. In robotmainwindow.h, I forward declared robotTabWidget as such:
robotTabWidget* robotttabwidget;
Then, in robotmainwindow.cpp, I initialized the class:
robottabwidget = new robotTabWidget();
I have function called create connections in robotmainwindow, in which I try to connect a signal from robotTabWidget to a slot in robotmainwindow:
void robotmainwindow::createConnections()
{
connect(robottabwidget, &robotTabWidget::sigSendCartCommand, this, &robotmainwindow::slotOnSendCartCommand);
}
The signal sigSendCartCommand is defined in robottabwidget.h:
void sigSendCartCommand(double);
And emitted in robotTabWidget::on_SendCartCommand_clicked():
emit sigSendCartCommand(CartCommand);
But when I attempt to compile, I get a "no matching function for call to" for the connect function, and "robotTabWidget::sigSendCartCommand(double) is protected". Why is the signal protected? I thought you could emit a signal from anywhere. And why am I getting a "no matching function" error?
This has been giving me a lot of trouble for the last few days and I haven't been able to figure it out. I'd greatly appreciate your help!
edit: I've changed things around, and fixed a few things but I'm still getting errors. The connect function now looks like:
QObject::connect(myrobotTabWidget, robotTabWidget::sigTest(test), this, &robotmainwindow::slotOnSendCartCommand);
The error I'm now getting is "cannot call member function without object":
../RobotInterface2/robotmainwindow.cpp:102:68: error: cannot call member function 'void robotTabWidget::sigTest(QString)' without object
QObject::connect(myrobotTabWidget, robotTabWidget::sigTest(test), this, &robotmainwindow::slotOnSendCartCommand);
And the arrow is pointing at robotTabWidget::sigTest(QString). I'm not sure what to do about this. Any ideas?

signal slot issue in qt 5

I have one c++ class and have one signal in it and want to connect that signal with slot another C++ class. Here is my code
class Data : public QObject
{
Q_OBJECT
public:
static Data *instance(void);
signals:
void sendUserID(const QString& userId);
private:
static Data *s_instance;
};
here is my Slot in another class
void DataDetails::seTUserID(const QString user_id)
{
QAndroidJniObject user_id = QAndroidJniObject::fromString(user_id);
QAndroidJniObject::callStaticMethod<void>("com/user/data/userActivity",
"setUserID",
"(Ljava/lang/String;)V",
user_id.object<jstring>());
}
The idea is to access the value of user_id from Data class to DataDetails class
The connection is trying is
QObject::connect(&s_instance, SIGNAL(sendUserID(uid), this, SIGNAL(setUserID(uid))
any other id to get uid to other class is also fine ..
Generally speaking, when you encounter an issue with QObject::connect...
Make sure you have your declarations in order:
Both classes need the Q_OBJECT macro in their declaration.
Make sure your slot is actually declared as a slot (i.e. is part of a public slot: section).
Because connecting signals and slots just uses character strings evaluated at run-time, it's possible to write absolute nonsense and have it compile. In my experience, errors caused by typos are pretty common.
Always test in an environment where you can see your application's console output. Failed connect calls will usually trigger an error message printed to stderr.
Double-check your method names and signatures. Code will still compile even if you've made a typo!
For debugging, use assertions (e.g. bool c = connect(...); Q_ASSERT(c);) to catch missed connections early.
Alternatively, you can use the QMetaMethod-based version of QObject::connect, introduced in Qt 4.8, to avoid some of these issues.
In your particular case:
You've got a typo in the function declaration: it's called seTUserID but you're using setUserID in the connect call.
You're using variable names, not function signatures, in your signal and slot names. Qt expects to see QObject::connect(&s_instance, SIGNAL(sendUserID(const QString), this, SLOT(setUserID(const QString))
You've got a signal connected to another signal, which is valid but doesn't do what you want (it's usually used to chain stuff like this: SomeChildWidget's signal -> MyClass1's signal -> MyClass2's slot).
Check that seTUserID definition is marked as slot. You are probably calling connect in some Data method (because you are using private member directly). Are you trying to use a ref to a pointer to s_instance O_o? Write sendUserID(const Qstring) (the signature of a signal) rather then sendUserID(uid). The same situation with setUserID. You are trying to connect to this pointer and want to send info to another class!? Use new style of Qt connecting signals and slots (pointers to members), with was introduced in Qt 5. Check for setUserID has written right.