I have a problem. All is great when I compile, but slots don't work. After application starts, it outputs QObject::connect: No such signal CMatrix::ReadyToDraw(ww). I tested it, slot DrawFunction() doesn't work. I can't debug because of segmentation fault.
header.h
class CMatrix:public QObject
{
Q_OBJECT
public:
int **m_pMatrix;
const short int m_size=4;
public:
CMatrix();
bool checkFields();
void setField();
signals:
void ReadyToDraw(CMatrix *ww);
public slots:
void MoveDown();
void MoveTop();
void MoveLeft();
void MoveRight();
};
class MainWindow : public QWidget
{
Q_OBJECT
public:
MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void DrawFunction(CMatrix *A);
public:
QPushButton* butTop;
QList<QLabel*> lblList;
};
main.cpp
#include "header.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
CMatrix *ww=new CMatrix;
QObject::connect(w.butTop,SIGNAL(clicked()),ww,SLOT(MoveTop()));
QObject::connect(ww,SIGNAL(ReadyToDraw(ww)),&w,SLOT(DrawFunction(ww)));
w.show();
return a.exec();
}
your signals signature is
ReadyToDraw(CMatrix *)
not
ReadyToDraw(ww)
as connect() needs the type, not the name of the variable.
so change your connect line to:
QObject::connect(ww,SIGNAL(ReadyToDraw(CMatrix *)),&w,SLOT(DrawFunction(CMatrix *)));
Related
I have problem with sharing pointer to Pixmap via signal-slot mechanism.
Inside slot function I have correct QPixmap with fulled data.
In reciever I have unaccessible QPixmap with empty data.
Any ideas?
class A
{
public:
A:A():pixmap(0){};
void fillPixmap()
{
// correct Pixmap and data isn't null
}
public signals:
void sendQPixmapToB(QPixmap*);
private:
QPixmap *pixmap;
}
class B
{
public:
B:B(){};
public slots:
void recievePixmap(QPixmap* pixmap)
{
// here in debugger pixmap is unaccesible and data is 0
}
}
void onButtonClicked()
{
a.fillPixmap();
}
int main()
{
A a;
B b;
.....
connect(a, SIGNAL(sendQPixmapToB(QPixmap*)),b,SLOT(recievePixmap(QPixmap*)));
return 0;
}
I can not tell you what is wrong with your code because as you indicate you are showing a pseudo-code, so I will show you the correct way to do it.
#include <QGuiApplication>
#include <QPixmap>
#include <QTimer>
#include <QDebug>
class A: public QObject{
Q_OBJECT
public:
using QObject::QObject;
void sendPixmap(){
fillPixmap();
emit sendQPixmapToB(pixmap);
}
signals:
void sendQPixmapToB(const QPixmap & pixmap);
private:
void fillPixmap(){
pixmap = QPixmap(64, 64);
pixmap.fill(Qt::red);
}
QPixmap pixmap;
};
class B: public QObject{
Q_OBJECT
public:
using QObject::QObject;
public slots:
void recievePixmap(const QPixmap & pixmap){
qDebug()<<pixmap;
}
};
int main(int argc, char *argv[])
{
QGuiApplication a(argc, argv);
A obja;
B objb;
QObject::connect(&obja, &A::sendQPixmapToB, &objb, &B::recievePixmap);
QTimer::singleShot(1000, &obja, &A::sendPixmap);
return a.exec();
}
#include "main.moc"ยท
I want to update UI from the second thread, I have created slots which are going to be called from other thread by signaling, but somehow it is not being called from the other thread. Below is the code:
WorkerThread.h
class WorkerThread: public QObject
{
Q_OBJECT
public:
WorkerThread();
~WorkerThread();
public slots:
void onStart();
signals:
void sendMessage(const QString& msg, const int& code);
};
WorkerThread.cpp
#include "workerwhread.h"
WorkerThread::WorkerThread(){}
void WorkerThread::onStart(){
emit sendMessage("start", 100);
}
Usage:
MyWidget.h
namespace Ui {
class MyWidget;
}
class MyWidget: public QWidget
{
Q_OBJECT
public:
explicit MyWidget(QWidget *parent = 0);
~MyWidget();
private slots:
void onGetMessage(const QString &msg, const int& code);
private:
Ui::MyWidget *ui;
QThread *thread = nullptr;
WorkerThread *wt = nullptr;
};
MyWidget.cpp
MyWidget::MyWidget(QWidget *parent) : QWidget(parent), ui(new Ui::MyWidget)
{
ui->setupUi(this);
wt = new WorkerThread;
thread = new QThread;
connect(thread, &QThread::finished, wt, &QObject::deleteLater);
connect(ui->btStart, &QPushButton::clicked, wt, &WorkerThread::onStart);
connect(wt, &WorkerThread::sendMessage, this, &MyWidget::onGetMessage);
wt->moveToThread(thread);
thread->start();
}
void MyWidget::onGetMessage(const QString &msg, const int& code)
{
qDebug() << "message" << msg; // this never being called ????
}
Note: When I pass the connection type Qt::DirectConnectoin, then it is working, but the problem is it is not the GUI thread.
connect(wt, &WorkerThread::sendMessage, this, &MyWidget::onGetMessage, Qt::DirectConnection);
Main
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
w.setWindowIcon(QIcon(":/icons/system.png"));
return a.exec();
}
After a lot of trying and checking the code line by line, I finally found the problem. The reason was with overriding the event() function of QWidget, the return value of event() function is bool, so if you return a true it is OK and working well without throwing any runtime or compile-time error. But it will prevent signal-slot events to happen.
So NOT return true, but return QWidget::event(event); then it will slove the problem.
I would like share a string between two instances of QWidget.
In main.cpp, two objects are instantiated and shown like this:
#include "dialog.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Dialog w1,w2; //Derived from QWidget
w1.show();
w2.show();
return a.exec();
}
I would introduce SharedState class:
// shared_state.h
#ifndef SHARED_STATE_HPP
#define SHARED_STATE_HPP
#include <QObject>
class SharedState : public QObject
{
Q_OBJECT
public:
SharedState(QString initialValue = "")
: currentValue(initialValue)
{}
QString getCurrentValue()
{
return currentValue;
}
public slots:
void setValue(QString newValue)
{
if(currentValue != newValue)
{
currentValue = newValue;
emit valueChanged(currentValue);
}
}
signals:
void valueChanged(QString);
private:
QString currentValue;
};
#endif // SHARED_STATE_HPP
Now I would provide reference to SharedState in Dialog's constructor,
// dialog.h
#ifndef DIALOG_H
#define DIALOG_H
#include <QWidget>
#include "shared_state.h"
namespace Ui {
class Dialog;
}
class Dialog : public QWidget
{
Q_OBJECT
public:
explicit Dialog(SharedState& state, QWidget *parent = 0);
~Dialog();
private slots:
void handleTextEdited(const QString&);
public slots:
void handleInternalStateChanged(QString);
private:
Ui::Dialog *ui;
SharedState& state;
};
#endif // DIALOG_H
You may have noticed that I have added two slots, one to handle the case when the text is manually edited and one when shared state will inform us that we are out of date.
Now in Dialog's constructor I had to set initial value to textEdit, and connect signals to slots.
// dialog.cpp
#include "dialog.h"
#include "ui_dialog.h"
Dialog::Dialog(SharedState& state, QWidget *parent) :
QWidget(parent),
ui(new Ui::Dialog),
state(state)
{
ui->setupUi(this);
ui->textEdit->setText(state.getCurrentValue());
QObject::connect(ui->textEdit, SIGNAL(textEdited(QString)),
this, SLOT(handleTextEdited(QString)));
QObject::connect(&state, SIGNAL(valueChanged(QString)),
this, SLOT(handleInternalStateChanged(QString)));
}
Dialog::~Dialog()
{
delete ui;
}
void Dialog::handleTextEdited(const QString& newText)
{
state.setValue(newText);
}
void Dialog::handleInternalStateChanged(QString newState)
{
ui->textEdit->setText(newState);
}
Now the change in the main function:
// main.cpp
#include "dialog.h"
#include "shared_state.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
SharedState state("Initial Value");
Dialog w1(state), w2(state);
w1.show();
w2.show();
return a.exec();
}
I'm trying to set the connect() like this:
QObject::connect(&webControl,
SIGNAL(Ui::MainWindow::loadFinished(bool)),
&w,
SLOT(Ui::MainWindow::loadFinished(bool)));
in main() function but it give the error:
QObject::connect: No such signal
QWebView::Ui::MainWindow::loadFinished(bool)
w and webControl are declared like this:
MainWindow w;
QWebView webControl;
And here's my files:
mainWindow.h
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
public slots:
void loadFinished(bool arg1);
private:
Ui::MainWindow *ui;
};
mainWindow.cpp
void MainWindow::loadFinished(bool arg1)
{
}
Why I'm getting this error and how do I fix this?
You need to add QWebView *webView; to your mainwindow.h:
mainwindow.h
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
QWebView *getWebView() const;
public slots:
void loadFinished(bool arg1);
void setWebView(QWebView *webControl);
private:
Ui::MainWindow *ui;
QWebView *webView;
};
mainwindow.cpp
...
QWebView *MainWindow::getWebView() const
{
return webView;
}
void MainWindow::setWebView(QWebView *webControl)
{
webView = webControl;
QObject::connect(webControl,
SIGNAL(loadFinished(bool)),
this,
SLOT(loadFinished(bool)));
}
If you really need declaration of QWebView in main.cpp then pass pointer to setWebView() function:
main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
QWebView webControl;
w.setWebView(&webControl);
w.show();
return a.exec();
}
Your problem is that QWebView webControl; webcontrol is a qwebview and your signal is not in QWebview, but in MainWindow. You need that signal in QWebView. That is why its complaining about a signal that can't be found.
EDIT
You have a problem knowing what is a slot, and what a signal. Thy are two different things. A signal is like an alarm. An slot is the receiver and it works as a normal function.
If you want your webControl var to be the sender, then you have to declare the signal like this in y our QWebView.h class :
signals:
void yourSignalName(bool arg1);
and use the connect like this:
QObject::connect(&webControl,
SIGNAL(yourSignalName(bool)),
&w,
SLOT(loadFinished(bool)));
I'd suggest the new Qt5 syntax (which is optional):
QObject::connect(&webControl, &Ui::MainWindow::loadFinished,
&w, &Ui::MainWindow::loadFinished);
more on the new syntax: http://wiki.qt.io/New_Signal_Slot_Syntax
I have created a library which has following interface and callback.
I wanted to Implent it using QT Signal and Slot.
Is is possible to replace IWifiCameraDiscovery with Signal and slot
class IWifiCameraDiscovery
{
public:
virtual int InitialiseWiFiDiscovery(IWifiCameraEnumerationCallback*) = 0;
virtual void UnInitialiseWiFiDiscovery() = 0;
virtual int EnumerateWiFiDevice() = 0;
};
class IWifiCameraEnumerationCallback
{
public:
virtual void onWiFiDeviceDiscovered( WiFiDeviceInfo* pDeviceInfo,unsigned short nNoOfDevice) = 0;
virtual void onDiscoveryTimeout() = 0;
};
Yes, in a quite straightforward way.
class IWifiCameraDiscovery
{
public:
virtual int InitialiseWiFiDiscovery() = 0;
virtual void UnInitialiseWiFiDiscovery() = 0;
virtual int EnumerateWiFiDevice() = 0;
signals:
void onWiFiDeviceDiscovered(WiFiDeviceInfo* pDeviceInfo, unsigned short nNoOfDevice);
void onDiscoveryTimeout();
};
In your implementation, instead of calling the callbacks directly:
callback.onWiFiDeviceDiscovered(pDevInfo, x);
You would emit a signal:
emit onWiFiDeviceDiscovered(pDevInfo, x);
And you would use QObject::connect to connect these signals to your actual receivers (slots) on the other end. Be aware that emitting a signal is more expensive than calling a virtual function.
try this simple example
#include <QApplication>
#include <QFont>
#include <QPushButton>
#include <QWidget>
class MyWidget : public QWidget
{
public:
MyWidget(QWidget *parent = 0);
};
MyWidget::MyWidget(QWidget *parent)
: QWidget(parent)
{
setFixedSize(200, 120);
QPushButton *quit = new QPushButton(tr("Quit"), this);
quit->setGeometry(62, 40, 75, 30);
quit->setFont(QFont("Times", 18, QFont::Bold));
connect(quit, SIGNAL(clicked()), qApp, SLOT(quit()));
}
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
MyWidget widget;
widget.show();
return app.exec();
}
you can use like this
class IWifiCameraDiscovery
{
public slots:
void UnInitialiseWiFiDiscovery();
signals:
void EnumerateWiFiDevice();
}