Menu action connection does not find slot - c++

I am creating a QSystemTrayIcon traymenu. Its contextmenu has several actions which I need to identify.
public slots:
void s_showNote();
void Traymenu::createMainContextMenu(){
...
std::string noteTitle = m_noteList[i]->getTitle();
QString menuEntryName = QString::fromStdString(noteTitle);
QAction *openNote = m_mainContextMenu.addAction(menuEntryName);
QObject::connect(openNote,SIGNAL(triggered() ),this,SLOT(s_showNote()) );
QVariant noteID;
noteID.setValue(m_noteList[i]->getID());
openNote->setData(noteID);
The error is
QObject::connect: No such slot QSystemTrayIcon::s_showNote()
All of the code above is a part of my class definition that inherits from QSystemTrayIcon. How can I call the SLOT?

You seem to have at least two issues ongoing:
Use Q_OBJECT for QObject derived classes.
You will need to re-run qmake correspondingly.
As for the first point, please use C++11 and at least Qt 5.2 in the future because in cases like this, you will get a static compiler time error which comes handy for avoiding these tedious issues.

Related

QComboBox signal not trigged

I have checked my code several times and i still can't get why it is not working.
I use a QComboBox connected to a slot in the class like this :
this->choixCam = new QComboBox;
this->choixCam->addItem("Camera 1");
this->choixCam->addItem("Camera 2");
this->choixCam->addItem("Camera 3");
this->choixCam->addItem("All cameras");
QObject::connect(this->choixCam, SIGNAL(currentIndexChanged(int)), this, SLOT(this->selectCam(int)));
This previous part of code is defined is the constructor of my class MainWindows, called in the main. The definition in the header file is the following :
public:
QComboBox* choixCam;
public slots:
void selectCam(int choixCam);
I tried with successfully to run the slot from another signal.
Using the signal with QString, the signal activated(int) or trying an exemple find on the net didn't work neither. Signals/slots mecanism also work for QButton and QSpinBox.
I am running out of idea. Some help would be very appreciate.
Thank you.
#eyllanesc answer should work. Just change SLOT(this->selectCam(int)) to SLOT(selectCam(int)).
But why isnt it the same for QT?
Lets have a look at the connect method:
QMetaObject::Connection QObject::connect(const QObject *sender, const char *signal,const QObject *receiver, const char *method,
Qt::ConnectionType type)
(https://github.com/qt/qtbase/blob/e4c39d5e1e7ee8c2bba273e6d613ec519b7fa9c2/src/corelib/kernel/qobject.cpp#L2659)
and at the SIGNAl and SLOT definition:
#define SLOT(a) "1"#a
#define SIGNAL(a) "2"#a
QT uses c-strings to identify the signals and slots for qobjects.
These strings are used as keywords in some kind of dictionary over all qobjects, signals and slots.
Just try std::cout << SIGNAL(some text) << std::endl; to see what SIGNAL and SLOT do.
Thats why can call connect even without SIGNAL and SLOT:
connect(this->choixCam, "2currentIndexChanged(int)", this, "1selectCam(int)");
Now you know that
SLOT(this->selectCam(int)) will produce "1this->selectCam(int)" as keyword instead of "1selectCam(int)"
The SIGNAL and SLOT definitions are used because most IDEs disable C++ autocompletion inside quotation marks, which makes it hard to write the correct function signature.

QObject::sender() doesn't work properly in a slot

I want to make a button to stay pushed after a click. So I made a slot make_pushed which I try to use for that purpose. The button which was clicked on is identified by QObject::sender() method. But something goes wrong since it doesn't work.
QPushButton * size=new QPushButton("size",this);
connect(size, SIGNAL(clicked()), this, SLOT(make_pushed()));
void Window4::make_pushed()
{
QObject* sender = this->sender();
QPushButton* button = qobject_cast<QPushButton*>(sender);
button->setDown(true);
button->setText("Yep");
}
class Window4 : public QWidget
{
public:
Window4(QWidget * parent=0);
private slots:
void make_pushed();
};
There's a mistake in application output "QObject::connect: No such slot QWidget::make_pushed() in" , although everything compiles and the window appears. The problem is the slot is apparently not found, although it is in the same cpp file and in the header. And therefore when clicked, the botton neigher changes its text nor stays pushed.
You just forgot Q_OBJECT macro in class declaration http://doc.qt.io/qt-5/qobject.html:
Notice that the Q_OBJECT macro is mandatory for any object that implements signals, slots or properties. You also need to run the Meta Object Compiler on the source file. We strongly recommend the use of this macro in all subclasses of QObject regardless of whether or not they actually use signals, slots and properties, since failure to do so may lead certain functions to exhibit strange behavior.
http://doc.qt.io/qt-5/qobject.html#Q_OBJECT:
The Q_OBJECT macro must appear in the private section of a class definition that declares its own signals and slots or that uses other services provided by Qt's meta-object system.
Note: This macro requires the class to be a subclass of QObject. Use Q_GADGET instead of Q_OBJECT to enable the meta object system's support for enums in a class that is not a QObject subclass.
Just use it like this every time you subclass QObject/QWidget/...:
#include <QObject>
class Counter : public QObject
{
Q_OBJECT
// ...
}

Qt Minimized Taskbar Icon Mouse Event

I've tried virtually every way possible to hook the activated() signal of a taskbar icon to a corresponding slot. However, I do not understand why Qt(Qt5 Cretor) says I don't have a matching function for the slot.
Qt Error:
C:\Users\potato\Desktop\CCT-master\CCTracker\cctsystemtray.cpp:40:
error: no matching function for call to
'QObject::connect(QSystemTrayIcon*&, const char*, CCTSystemTray*
const, const char*)'this,
SLOT(systrayActivated(QSystemTrayIcon::ActivationReason)))
As far as I can tell, according to Qt Documentation,
The activated() signal is used to catch mouse events such as clicks and double clicks for the taskbar icon. At first try I thought it's only signals and slots, but then for whatever reason activated() just won't fit. And If I try connecting activated() to a slot from another class, everything fails due to pointer errors.
Here's are the working parts inside CCTSystemTray.h:
class CCTSystemTray
{
public:
CCTSystemTray();
void initSystemTray(QWidget *rootWindow);
private:
QSystemTrayIcon* systray;
public slots:
void systrayActivated(QSystemTrayIcon::ActivationReason);
};
And CCTSystemTray.cpp:
// Above are Class declearations, menu items, etc...
QObject::connect(this->systray, SIGNAL(QSystemTrayIcon::activated(QSystemTrayIcon::ActivationReason reason)),
this, SLOT(systrayActivated(QSystemTrayIcon::ActivationReason)));
}
void CCTSystemTray::systrayActivated(QSystemTrayIcon::ActivationReason)
{
qDebug() << "Hello";
}
The full code sample can be found here on pastebin.
If someone can help me out from hair-pulling, that'd be great!
Thank you all.
Your class CCTSystemTray has a slot, but it is not a QObject (it doesn't derive from QObject or another class derived from QObject) and also you need the Q_OBJECT macro in your class declaration and then signals and slots will work.

can't connect QT signal

i am new to QT and was trying to create a custom signal that would tell me a removable disk has been inserted.
This is what i did
MainWindow.h
class MainWindow
{
QOBJECT
..
..
signals:
void qm_diskInserted(QString &);
public slots:
void addItemToList(QString &);
...
}
MainWindow.cpp
void MainWindow::onDeviceChange(MSG * msg)
{
//code for detecting device here
QString &driveLetter= getDriveLetter(mask);
//try to emit QT signal here
emit qm_diskInserted(driveLetter);
}
MainWindow::MainWindow(QWidget * parent=NULL)
{
ui.setupUi(this);
QObject::connect(this, SIGNAL(qm_diskInserted(QString&)), this, SLOT(addItemToList(QString &));
}
void MainWindow::addItemToList(QString &)
{
//more stuff here
}
somehow the slot addItemToList() isn't called and i have to call it manually.
What am i doing wrong?
Thanks.
PS:
By the way is there any way of debugging signals?
Ie how can i be sure that a signal is emitted?
It is at least supposed to be Q_OBJECT. I think you also need to inherit QMainWindow.
This is a long shot, but are you sure onDeviceChange() method is called?
EDIT
Classes which have Q_OBJECT macro in their body needs to inherit directly or indirectly from QObject, and in your code it is not the case.
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.
Try making your signals virtual void instead and make sure that your MainWindow class inherits (directly or indirectly) from QObject
EDIT
As mentioned in other comments, the macro should be Q_OBJECT

qt GUI connecting

I am just starting out with QT. I have read through some tutorials, and I think I have an understanding of signals and slots. I am writing a GUI that has various buttons that change the state of my main program. So for example in a drawing app, you would pick different drawing tools (using various buttons).
What is the best way to go about this? My first thought was to try to connect the clicked signal of the PushButton to some function that sets a current_tool variable. I did some searching and couldn't find a way to connect a QObject signal to a regular function.
This leads me to believe that there is probably a different approach. One where I create a new QObject (my own extension that is) that has various GUI properties. I would then define my slots here for the various buttons.
What is the best way to do this in QT. I am new and do not know of the preferred practice.
Any info would be useful,
thanks
You can define these "normal functions" as slots. Slots are just normal functions that can also be called by signals:
class ToolSelector : public QObject {
Q_OBJECT
public:
Tool *selected;
public slots:
void selectBrush();
void selectPen();
void selectFill();
};
ToolSelector::selectBrush() {
delete selected;
selected = new Brush();
}
ToolSelector::selectPen() {
// ...
}
// ...
toolsel = new ToolSelector();
brushButton = new QPushButton();
connect(brushButton, SIGNAL(clicked()), toolsel, SLOT(selectBrush()));
Inherit from the class that uic generates, creating, say, a MyAppWindow class. Provide extra METHODs in that class, as well as a Document or Drawing object. Connect these methods to the signals you're interested in, and them alter a member variable that contains the drawing state.