No matching signal for QAction, no "go to slot" menu entry - c++

I have problem with actually running QActions created with QtCreator. To run e.g. actionSystemSettings, I've added slot to MainWindows so it looks like this:
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void on_menuWork_actionSystemSettings();
private:
Ui::MainWindow *ui;
};
And this:
void MainWindow::on_menuWork_actionSystemSettings() {
qDebug() << "Yay!";
}
It prompts:
QMetaObject::connectSlotsByName: No matching signal for
on_menuWork_actionSystemSettings()
I guess it's some dumb mistake and I just forgot about something but reading documentation gives me nothing. I have no "go to slot" menu entry which should auto-create some template... at least Visual Studio for C# did that.

When you're defining slots the correct way is:
on_<widget_name>_<signal>
for instance if you have to name your slot
private slots:
on_actionSystemSettings_triggered();
See QtAutoConnect

According to the documentation for QMetaObject::connectSlotsByName():
Searches recursively for all child objects of the given object, and
connects matching signals from them to slots of object that follow the
following form:
void on_object-name_signal-name(signal-parameters);
So, I think your slot should have the following signature:
void MainWindow::on_actionSystemSettings_triggered()
{
//
}

Related

C++ Qt Segmentation fault when trying to access method of an object

I am learning Qt, and I have come up with a problem. I would like some help, here as I tried changing variables and debugging it, but haven't come up with a solution. I'll provide some code to understand the problem i have
In my ColorButton.h class file
class ColorButton : public QToolButton
{
Q_OBJECT
public:
explicit ColorButton(const QColor &color, QWidget *parent = 0);
void testMethod();
};
My ColorButton.cpp file is like this
ColorButton::ColorButton(const QColor &color, QWidget *parent)
{
//some code
}
void ColorButton::testMethod()
{
//This is
//a test method
}
I am trying to access this testMethod() from another class.
From this class, header file is Toolbar.h
class ToolBar : public QToolBar
{
Q_OBJECT
public:
explicit ToolBar(const QMap<ToolsEnum, QAction*> &actionMap, QWidget *parent = 0);
private:
void setToolbar(); //initialize items
ColorButton *test; //-----
public slots:
void setMainColorView();
}
The Toolbar.cpp file is like this
ToolBar::ToolBar(const QMap<ToolsEnum, QAction *> &actionMap, QWidget *parent) :
QToolBar(tr("Tools"),parent), actionMapVar(actionMap)
{
setToolbar();
}
void ToolBar::setToolbar()
{
test = new ColorButton(QColor("#8C001A"));
}
void ToolBar::setMainColorView()
{
test->testMethod();
}
}
The program works when i put test->testMethod(); into setToolbar() , but I want to create the object in setToolbar() and call the method in setMainColorView().
So far I have tried making the Color button variable public,
I have also tried initializing the object called test in the constructor, but both don't work.
Right now, with this code the error I get is
"The inferior stopped because it received a signal from the operating system.
Signal name: SIGSEGV
Signal meaning: Segmentation fault"
with an arrow pointing at test->testMethod(). I have no clue how to solve it, any help would be appreciated
I was looking at the wrong place the entire time. I solved this by passing my toolbar object into the class i was calling setMainColorView() from. In that class i made a local variable of the toolbar object, assigned this. And then it worked.

Qt pass variables between forms

I want to pass a string from a form that is opened by the first form to the first form.
I am new to C++.
Here is my code.
Form1.h // main form
#include "dialog.h"
namespace Ui {
class Form1;
}
class Form1 : public QMainWindow
{
Q_OBJECT
public:
explicit Form1(QWidget *parent = 0);
~Form1();
void refresh(QString str_local);
private slots:
void on_pushButton_clicked();
private:
Ui::Form1 *ui;
Dialog *dialog1;
};
// form1.cpp
void Form1::on_pushButton_clicked()
{
dialog1= new Dialog; //Create new form with other class
dialog1->show();
QObject::connect(dialog1, SIGNAL(change(str_remote)), this, SLOT(refresh(str_local))); //Connect when is emit signal cambia in the child form and pass the string to local function
}
void Form1::refresh(QString str_local)
{
qDebug() << "Back to main" << str_local;
ui->label->setText(str_local);
}
// dialog.h the second form that should pass the value to main form
...
class Dialog : public QDialog
{
Q_OBJECT
signals:
void change(QString s);
public:
explicit Dialog(QWidget *parent = 0);
~Dialog();
private slots:
void on_pushButton_clicked();
private:
Ui::Dialog *ui;
};
// dialog.cpp
...
void Dialog::on_pushButton_clicked()
{
QString name;
name = ui->lineEdit->text();
emit change(name);
this->close();
}
I get the error:
No such signal Dialog::change(str_remote) in ../Format/form1.cpp:22 .
You have some strange code in here:
QObject::connect(dialog1, SIGNAL(change(str_remote)), this, SLOT(refresh(str_local)));
Since your class already inherits QObject indirectly, you can simply drop the scope specifier.
You probably aim for using the new compilation-time syntax signal-slot mechanism.
You have not marked your slot as slot in the header file.
You are trying to use the old signal/slot syntax with variable names for the signal and slot as opposed to the types.
Your signal is not using the good practice of const T& (i.e. constant reference).
You are specifying this explicitly, whereas it can be dropped. This is just admittedly personal taste.
You do not follow the Qt signal/slot naming convention, e.g. your signal is a verb rather adjective. It is also too generic, rather than "fooChanged" as the good practice goes.
There are other issues in your code as well, but this time I only focused on that one line. I would use this line with modern Qt and C++ programming principles in mind:
connect(dialog1, &Dialog::changed, (=)[const auto &myString] {
ui->label->setText(myString);
});
However, since this requires CONFIG += c++14, if your compiler does not support that (e.g. VS2010), you can go for this:
connect(dialog1, SIGNAL(change(const QString&)), this, SLOT(refresh(const QString&)));

Create a custom slot in C++, Qt5

in python we write custom slots quite easily by passing in the function to be called when a signal is generated.
While in C++ connect function requires us to pass the address of the slot function or so i figured. How do i do that. I tried using this but did'nt work.
Python code::
class imviu(QtGui.QWidget):
def __init__(self):
super(imvui,self).__init__()
self.btn=QtGui.QPushButton('Browse')
btn.clicked.connect(self.openimg)
def openimg(self):
#do something
C++ code::
class imviu: public QWidget
{
public:
imviu(QWidget *parent=0);
QPushButton *btn=new QPushButton("Browse");
void openimg(void);
};
imviu::imviu(QWidget *parent)
:QWidget(parent)
{
connect(btn, SIGNAL(clicked()),this,SLOT(openimg()));//this does'nt work:QObject::connect: No such slot QWidget::openimg()
}
void imviu::openimg()
{
//do something
}
In order to use signals and slots, you need to have the Q_OBJECT macro in your class as well as identifying which functions should be the signals and the slots. Have a look at the documentation for a more in-depth explanation.
After this, you need to set up the project file so that MOC can generate the necessary code.
Your class definition should look like this:
class imviu: public QWidget
{
Q_OBJECT
public:
imviu(QWidget *parent=0);
public slots:
void openimg();
private:
QPushButton *btn;
};

QObject::connect not connecting signal to slot

I am using C++ and Qt in my project and my problem is QObject::connect function doesn't connect signal to a slot. I have the following classes:
class AddCommentDialog : public QDialog
{
Q_OBJECT
public:
...some functions
signals:
void snippetAdded();
private slots:
void on_buttonEkle_clicked();
private:
Ui::AddCommentDialog *ui;
QString snippet;
};
A part of my Main window:
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void commentAddedSlot();
void variableAddedSlot();
...
private:
AddCommentDialog *addCommentDialog;
...
};
Ant the last dialog;
class AddDegiskenDialog : public QDialog
{
Q_OBJECT
public:
...
signals:
void variableAdded();
private slots:
void on_buttonEkle_clicked();
private:
Ui::AddDegiskenDialog *ui;
...
};
In the main window constructor i connect signals and slots:
addCommentDialog=new AddCommentDialog();
addDegiskenDialog=new AddDegiskenDialog();
connect(addDegiskenDialog, SIGNAL(variableAdded()), this, SLOT(variableAddedSlot()));
connect(addCommentDialog, SIGNAL(snippetAdded()), this, SLOT(commentAddedSlot()));
The point is my commentAddedSlot is connected to it's signal successfully, but commentAddedSlot is failed.
There is the Q_OBJECT macros, no warning such as about no x slot. In addition to this,
receivers(SIGNAL(snippetAdded())) gives me 1 but receivers(SIGNAL(variableAdded())) gives me 0 and i used commands qmake -project; qmake and make to fully compile.
What am i missing?
Quick look at your code gives no ideas what is your problem.
But, here are some moments:
As Mike said here: With connection problems, always make sure that you check the console for messages about connect failures. Since Qt can't tell if a connection makes sense until runtime, it notifies you of failures there. You'd think it would crash, but it just quietly says these things in the console.
With Qt, it makes sense to watch the console always. Qt prints out all sorts of error messages that can help when you've got a problem.
You can control result of connect function, so (from official documentation)
The function returns true if it successfully connects the signal to
the slot. It will return false if it cannot create the connection, for
example, if QObject is unable to verify the existence of either signal
or method, or if their signatures aren't compatible.
Check if your objects (dialogs) creates well and pointers is not equal to NULL.
Try to clear your project ("Clear project" command in QtCreator), even manually delete all ui_*, moc_*. And then recompile it.
Good luck! And, please, give us feedback.

How can I overwrite the "next" slot in a QWizard?

I'm using a QWizard class, which contains several QWizardPage. For some pages, I need to do something when the "Next" button is clicked.
I tried to overwrite the next slot in my QWizard class; however, it seems this doesn't work. The program still went into the original next slot in the parent QWizard class instead of the one I implemented.
Is this because this next slot is virtual protected? How can I do some things after the next button is clicked?
The header file of my QWizard class follows. By the way, the accept signal works fine as what I expected.
#ifndef PRIMERWIZARD_H
#define PRIMERWIZARD_H
#include <QWizard>
namespace Ui {
class PrimerWizard;
}
class PrimerWizard : public QWizard {
Q_OBJECT
public:
PrimerWizard(QWidget *parent = 0);
~PrimerWizard();
protected slots:
void next();
void accept();
protected:
void changeEvent(QEvent *e);
private:
Ui::PrimerWizard *ui;
};
#endif // PRIMERWIZARD_H
I create a new wizard instance via QtCreator's wizard (Ha XD)
The code is as follows:
PrimerWizard* pW = new PrimerWizard(this);
pW->exec();
And the signal-slot connection of next is created by QtCreator, I cannot find where it's actually connected. I think the connection is built in ui_PrimerWizard.h by this function:
QMetaObject::connectSlotsByName(PrimerWizard);
The next slot cannot be overwritten. However, the validatePage function for QWizardPage can. This function will be called when the "Next" or "Finish" button is clicked.