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
Related
I was trying to connect signal QListWidget->itemChanged to a custom Slot called checkItemChanged. I asked for right syntax in this question.
I'm using QT4 so I used old-string syntax as below to connect signal and slot:
connect(listWidget, SIGNAL(itemChanged(QListWidgetItem*)), this , SLOT(checkItemChanged(QListWidgetItem*)));
This connect syntax is declared in a file called mainWindow.cpp and its header file mainWindow.h is as below:
class mainWindow : public QWidget
{
Q_OBJECT
public:
mainWindow ( QWidget *parent=0, const char *name=0 );
public slots:
void checkItemChanged(QListWidgetItem*);
I also defined my slot implementation in mainWindow.cpp as below:
void mainWindow::checkItemChanged(QListWidgetItem* item)
{
if (item->checkState()==true){
qDebug()<<"Item: "<<item->text()<<"Checked";
}else{
qDebug()<<"Item: "<<item->text()<<"UnChecked";
}
}
So it used macro Q_OBJECT as answered here as common reason for no such slot error.
I run my project in KDevelop IDE, so it will automatically build .moc file and run qmake as asked in this answer
However still I face error as below:
Object::connect: No such slot mainWindow::checkItemChanged(QListWidgetItem*) in /home/part/Desktop/project/P/src/gui/mainWindow.cpp:320
I know this is strange but I want to know may be it is related to the fact that QListWidget->itemChanged is protected? Or there are some other thing that I have missed?
I have a MainWindow with two widgets, buttonsWidget and infoWidget.
I'm trying to to hide infoWidget after clicking a button within buttonsWidget (and ultimately show a different widget).
I've tried:
mainwindow.h
public:
void hideInfo();
mainwindow.cpp
void MainWindow::hideInfo()
{
ui->info->hide();
}
buttonsWidget.cpp
void buttonsWidget::on_timingButton_clicked()
{
MainWindow::hideInfo();
//Then will do something to show 'timingWidget'..
}
Many thanks
You should use Signals and Slots for this.
Add a signal in the buttonsWidget.h.
signals:
void hideInfoSignal();
In the main function, connect the button signal with the mainwindow method hideInfo().
QObject::connect(this->info, SIGNAL(hideInfoSignal),this, SLOT(hideInfo));
I haven't tested this, because I dont have Qt on this machine, but that should work, with possible minor modifications. If any errors appear, let me know and I will help. Also, read the signals and slots documentation.
I've got a question about signals and slots. In my app, I want to connect a signal from one object to a textEdit in a dialog window. My signal emits a QString; if I violate encapsulation (by making the UI public instead of private) and connect the signal directly to the textEdit it works. But I feel that it's not the right way. If I make something like the following:
connect(m_osgWidget->picker.get(), SIGNAL(setX(QString)), m_addAgentDlg, SLOT(getX(QString)));
where:
void getX(QString)
{
this->ui.textEdit(QString);
}
It gives me an error that I can't use QString in this this->ui.textEdit(QString); I need the QString from setX() signal pasted into the textEdit of m_addAgentDlg. How this can be done? Where did I make a mistake?
I am sorry to say this, but you need to learn basic C++. The proper syntax is this for such things in C++ with Qt:
connect(m_osgWidget->picker.get(), SIGNAL(setX(const QString&)), m_addAgentDlg, SLOT(getX(const QString&)));
// Why do you call it getX? Should it be called setText instead?
void getX(const QString& string)
{
ui->textEdit->setText(string);
}
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.
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.