Qt C++ WebKit windowCloseRequested Signal - c++

I am trying to connect QWebpage::windowCloseRequested() to a slot that just prints out a debug message. When I call window.close(); in JavaScript it doesn't bubble the signal up or call the slot...
connect(webView->page(), SIGNAL(windowCloseRequested()),this, SLOT(windowCloseRequested()));
The slot is setup, it is in my window.h file as a slot like this:
public slots:
void windowCloseRequested();
And the function is defined as:
void MyWindow::windowCloseRequested(){
qDebug() << "I was called";
}
When I compile, there are no errors, there were before saying I had the slots wrong, I figured that part out, no more error, but now when I click a link, or call window.close() with javascript in a loaded webpage, it doesn't do anything. If I manually call the function, it prints out the debug message.
Any pointers, or help/solutions would be appreciated. Note, this code above is based on the Tabwidget.cpp code for a browser example. It's the best reference I could find.

Attaching an onclick to an <a> tag is ... questionable. Use a span, and blammo, it works. This is why you should take breaks when coding, or else you make really dumb mistakes that waste time.

Related

Qt connect in constructor not connecting?

A google search gives these as the top three results:
Qt: Connect inside constructor - Will slot be invoked before object is initialized?
Qt can I connect signals/slots to self in constructor?
QT Connect Signal Slot and initialize in constructor
According to those, it seems like it ought to "just work" like anything else. But this code doesn't:
EditorList::EditorList(..., QWidget* parent) :
QWidget(parent)
{
...
Processing* processing = Processing::getInstance();
connect(this, SIGNAL(reorderDelete(DataSequence*,ListType,QList<int>)), processing, SLOT(reorderDelete(DataSequence*,ListType,QList<int>)));
...
buttonDelete = new QPushButton(this);
connect(buttonDelete, SIGNAL(clicked(bool)), this, SLOT(buttonDeleteClick()));
...
}
...
void EditorList::buttonDeleteClick()
{
...
QList<int> locations;
...
emit reorderDelete(mySequence, myListType, locations); //breakpoint 1 here
}
//-----------------------------------------------------------------
void Processing::reorderDelete(DataSequence* sequence, ListType listType, QList<int> locations)
{
if(sequence) //breakpoint 2 here
{
sequence->reorderDelete(listType, locations);
}
}
The reason for this structure, instead of calling mySequence->reorderDelete directly, is to have it done in Processing's thread instead of the UI's. I hope I haven't stripped out too much detail to show the problem; this is a rather large project.
When I click my delete button, I hit breakpoint 1 (so far, so good), but I don't hit breakpoint 2. My other signals/slots work across threads, but their connects are not in constructors. I want to make this one automatic so that every instance is "just connected" without having to remember to do it. Can I not do that?
Okay, I got it. Leaving up for others to find.
According to this, my ListType enum was blocking the system from making the connection. It only works with system-known datatypes because emitting a SIGNAL actually stores a copy for the SLOT(s) to read later. I knew that, but I thought it was more like a stack frame that could take anything. Apparently not.
It also works to put a call to qRegisterMetaType<ListType>("ListType"); somewhere before the connect. (I put it in my main window's constructor.) This makes the datatype known so that the connection can work anyway.
I'm hitting both breakpoints now.
Make sure you have used Q_OBJECT macros in your class

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?

QML type from C++ Plugin signaling only once

I have a C++ plugin that watches for file changes with QFileSystemWatcher and connects it's fileChanged signal with a custom QML type slot like this:
//In the custom QML type constructor
QObject::connect(&this->_watcher, SIGNAL(fileChanged(QString)),
this, SLOT(fileChangedSlot(QString)));
The slot function:
void CustomQMLTypeClass::fileChangedSlot(QString file)
{
Q_UNUSED(file);
emit fileChanged();
}
In the QML side:
CustomQMLType{
fileUri: "some/file/path/file.format"
onFileChanged: console.log("File changed")
}
While running the program all goes right, but when I do, i.e.:
echo "sth" >> some/file/path/file.format
More than once, the notification is only triggered once. Why? O.o
Apparently the problem is with QFileSystemWatcher, it sometimes worked and some others don't.
As I can handle the cost, my quick solution was to alter the slot:
void CustomQMLTypeClass::fileChangedSlot(QString &file)
{
_watcher.removePath(file);
_watcher.addPath(file);
emit fileChanged();
}
Now it works as expected but don't know why and couldn't get to understand neither with QFileSystemWatcher's source. Finally I decided KDE's KDirWatch is way better.

Qt - Detect item information change in QListView

I have a QListView which is connected to a QStandardItemModel. How do I detect any information change in the model or the QListView? I tried the Signals and Slots with the itemChanged() for the model but it seems to crash the whole program.
Qbject::connect(bugModel, SIGNAL(itemChanged(QStandardItem*)), this, SLOT(bugInfoChanged()));
That is the code I'm using to connect the Signal. the function bugInfoChanged() just runs a qDebug() that says "Changed". But when I start the program, it shows a crash error.
When I comment this line (//QObj...) then the crash doesn't occur, but again when I remove the comment it does crash. I have this in my "Private Slots" area:
void bugInfoChanged();
and it's like this in the cpp:
void MainWindow::bugInfoChanged()
{
qDebug() << "Changed";
}
I have no clue as to what causes the crash :/
I fixed it myself. Turns out if I place the connecting code in a function where the list is populated, it works just fine. It used to crash because the list didn't have any item at the moment when the App started.

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

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?