Qt matching signal with custom slot - qt

I'm trying to use a QAction (QMenu member entry) to open a new window. Precisely: I want actionAbout signal predefined activated to match MainWindow custom slot open AboutWindow - and that's what I've got trouble with.
I know that I can use either the connect Qt function manually inside the source main_window.cpp file or just click it up in the Qt Creator, but my custom slot doesn't show up so I cannot select it. Maybe my slot function declaration is wrong (invalid parameters) and that's why QtCreator doesn't allow me to choose my custom slot in the GUI signals & slots. Could anyone point me what should I do to make QtCreator display my custom slot in the dropdown and how should the connect function call look like?
This is my main_window.h file content:
#include
#include "about_window.h"
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
public slots:
void openAboutWindow();
private:
Ui::MainWindow *ui;
Ui::AboutWindow *aboutWindow;
};
And this is main_window.cpp:
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
connect(actionAbout, SIGNAL(activated()), this, SLOT(openAboutWindow(this));
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::openAboutWindow(QWidget *parent)
{
aboutWindow = new Ui::AboutWindow(parent); // Be sure to destroy you window somewhere
aboutWindow->show();
}
The compiler shouts about both constructor and openAbutWindow:
../Application/main_window.cpp: In constructor ‘MainWindow::MainWindow(QWidget*)’:
../Application/main_window.cpp:9:13: error: ‘actionAbout’ was not declared in this scope
../Application/main_window.cpp:9:80: error: expected ‘)’ before ‘;’ token
../Application/main_window.cpp: In member function ‘void MainWindow::openAboutWindow(QWidget*)’:
../Application/main_window.cpp:19:44: error: invalid use of incomplete type ‘struct Ui::AboutWindow’
../Application/about_window.h:7:11: error: forward declaration of ‘struct Ui::AboutWindow’
../Application/main_window.cpp:20:15: error: invalid use of incomplete type ‘struct Ui::AboutWindow’
../Application/about_window.h:7:11: error: forward declaration of ‘struct Ui::AboutWindow’

../Application/main_window.cpp:9:13: error: ‘actionAbout’ was not declared in this scope
The error message says it all, where is the QAction defined? Should it be ui->actionAbout?
connect(actionAbout, SIGNAL(activated()), this, SLOT(openAboutWindow(this));
openAboutWindow() does not take any arguments, and regardless this is an instance not a type.

Related

QTextBrowser for Helper

I am trying to make a helper with QTextBrowser. As I understood, home(), backward() and forward() are already implemented in QTextBrowser and required only connections to the buttons. Below there is .h and .cpp files
#ifndef HELPWINDOW_H
#define HELPWINDOW_H
#include <QDialog>
namespace Ui {
class HelpWindow;
}
class HelpWindow : public QDialog
{
Q_OBJECT
public:
explicit HelpWindow(QWidget *parent = 0);
~HelpWindow();
private slots:
private:
Ui::HelpWindow *ui;
};
#endif // HELPWINDOW_H
and
#include "helpwindow.h"
#include "ui_helpwindow.h"
HelpWindow::HelpWindow(QWidget *parent) :
QDialog(parent),
ui(new Ui::HelpWindow)
{
ui->setupUi(this);
// connection
connect(ui->pushButton_home,SIGNAL(clicked()),ui->textBrowser,SLOT(home()));
connect(ui->pushButton_forward,SIGNAL(clicked()),ui->textBrowser,SLOT(forward()));
connect(ui->pushButton_backward,SIGNAL(clicked()),ui->textBrowser,SLOT(backward()));
}
HelpWindow::~HelpWindow()
{
delete ui;
}
There is no any error message. It is possible to read and click the links inside QTextBrowser. Only there are no any actions with buttons. What do I miss here?
You need to call either one or both of the following properties
ui->textBrowser.setOpenLinks(true);
ui->textBrowser.setOpenExternalLinks(true);
and if you want filter or re-route the links at runtime
connect(ui->textBrowser, SIGNAL(sourceChanged(QUrl)), pointerToYourCode, SLOT(slotSourceChanged(QUrl)));
and implement
void YourCode::slotSourceChanged(const QUrl& url) {...}
I found why it did not work. The initial source should be specify:
ui->textBrowser->setSource(QUrl::fromLocalFile("help/index.html"));
Thank you, Jens for spending time.

Slot function is not called by currentChanged signal of treeView

I want to call a function indexChanged() if an index in my treeView is changed.
I used ui->treeView->currentChanged() signal but it didn't call indexChanged() slot, even though I connected the signal to the slot.
Here's my code :
.cpp file
TipManager::TipManager(QWidget *parent) :
QWidget(parent),
ui(new Ui::TipManager)
{
ui->setupUi(this);
connect(ui->treeView->selectionModel(), &QItemSelectionModel::currentChanged, this, &TipManager::indexChanged);
...
}
void TipManager::indexChanged(const QModelIndex &current, const QModelIndex &previous)
{
trimCurrentPath(previous);
}
.h file
namespace Ui {
class TipManager;
}
class TipManager : public QWidget
{
Q_OBJECT
public:
explicit TipManager(QWidget *parent = 0);
~TipManager();
public slots:
void indexChanged(const QModelIndex &current, const QModelIndex &previous);
private:
Ui::TipManager *ui;
...
};
I also tested in debug mode, but the slot function indexChanged() is not even called. Plus, it shows this message instead : QObject::connect: invalid null parameter
I hit a similar issue (the slot wasn't being triggered). Following #G.M.'s pointer in the comments to your question, it turned out that the call to ui->treeView->selectionModel() returns null if there's no model yet (and setSelectionModel() hasn't yet been called, presumably).
If I populated my QTreeView prior to calling ui->treeView->selectionModel() within the connect() call then I received my non-null response and the slot was triggered by the signal as desired.

connect QPushButton via lambda

I am trying to connect QPushButton to lambda expression:
QPushButton* loadTextFileButton = new QPushButton("load");
connect(loadTextFileButton, &QPushButton::clicked, [](){
qDebug()<<"clicked";
});
Compiler gives me an errors like: No matching function to call "MyClass::connect(..."
What I am doing wrong?
The connect function, which is part of Qt's signal and slots mechanism is Qt's extension to C++.
The connect function is actually a static function of QObject, so you can use it from anywhere, by simply including QObject: -
#include <QObject>
...
QObject::connect(itemPtr1, SIGNAL(someFunction()), itemPtr2, SLOT(someOtherFunction());
The objects itemPtr1 and itemPtr2 are pointers to instances of classes that are derived from QObject and support signals and slots.
In order for a class to use the signal and slot mechanism, it must inherit from QObject and declare the Q_OBJECT macro:-
class MyClass : public QObject
{
Q_OBJECT // the Q_OBJECT macro, which must be present for signals and slots
public:
MyClass(QObject* parent);
signals:
public slots:
private:
void StandardFunction();
};
As this class inherits QObject, it now has direct access to the connect function, allowing calling connect directly:-
QPushButton* loadTextFileButton = new QPushButton("load");
connect(loadTextFileButton, &QPushButton::clicked, []()
{
qDebug()<<"clicked";
});
Finally, Qt 5 introduced a new syntax for signals and slots: -
connect(loadTextFileButton, &QPushButton::clicked, this, &MyClass::StandardFunction);
You may have noticed that the advantage here is that the signal can be connected to a function that is not declared as a slot. In addition, using this syntax provides compile time error checking.

QT error in connecting passing a QString element

I was following some code posted in other questions on how to connect the status bar between parent and distant child by means of signals and slots.
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent)
{
...
connect(myCanvas,SIGNAL(mouseMoved(QString)),
this,slot(setStatusBar(QString)));
...
}
Somewhere in the class MainWindow the following is declared as public slot:
void MainWindow::setStatusBarText(const QString& text) {
statusBar()->showMessage(text);
}
in the class to which myCanvas belongs declares the signal:
signals:
void mouseMoved(const QString&);
And emits the signal:
void GraphicsView::mouseMoveEvent(QMouseEvent *mouseEvent)
{
...
emit mouseMoved(QString("("+QString::number(mouseMoveCatch.x())+";"
+QString::number(mouseMoveCatch.y())+")"));
...
}
I am sure QString is properly included. But when i compile I get an error on the connect line saying "QString does not refer to a value".
I have no clue what this means. Thanks for any help!
You have a case error on the line
connect(myCanvas,SIGNAL(mouseMoved(QString)),
this,slot(setStatusBar(QString)));
You should be using SLOT, not slot.

SIGSEGV with QMainWindow singleton

The application I am writting as unique instantiation of some classes which have to be accessible easily. For that i use singletons.
For exemple my Core is defined as :
class Core : public QObject
{
Q_OBJECT
public:
Core();
~Core();
static Core& getCore()
{
static Core mycore;
return mycore;
}
(...)
};
and it works just great. However I tried to do the same with my MainWindow class, which interits from QMainWindow. I need that in order to access methods such as geometry() from other objects
However Core works great, MainWindow makes error when clossing the programe. The main window destructor is called and executed apparently once ( debug using qDebug() ) but i still have a SIGSEGV signal. What's happening? How to solve it?
Here is the code of MainWindow
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = 0);
~MainWindow();
static MainWindow& getUi()
{
static MainWindow myUi;
return myUi;
}
public slots:
void refreshImage();
private:
Ui::MainWindow *ui;
};
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
connect(&appCore(), SIGNAL(refreshed()), this, SLOT(refreshImage()));
}
MainWindow::~MainWindow()
{
delete ui;
}
And the main code
QApplication app(argc, argv);
try
{
appCore().setDevice(MDMA::Kinect);
appUi().show();
return app.exec();
} catch(MDMA::exn e) {
(...)
}
where appCore and appUi are macros for Core::getCore and MainWindow::getUi()
This crash probably results from your QApplication being destroyed before the MainWindow.
If you cannot pass your MainWindow via other ways to the code where it is needed (e.g. as argument or via QObjecg::parent()), you could employ a technique similar to what QApplication does with it's instance method (a non-owning global reference):
Construct your MainWindow as an ordinary local variable on the stack, after the QApplication. Then set a global pointer (maybe better a QPointer; e.g. a static member of MainWindow), which you initially initialize to 0, to this in the constructor of MainWindow. You can also check if it was already initialized here to enforce the uniqueness. Via a public accessor method (instance?) for the global pointer, you can access the class from everywhere while ensuring destruction before QApplication.
If you want to make singletone, try to use general technics, for example, as described here:
http://www.qtcentre.org/wiki/index.php?title=Singleton_pattern
Hope, lot of questions will dissappear after reading all of that article.
As for me, there is nice and simple realization of singletone.
Good luck!

Resources