I want to execute a slot in different class. Is it possible
UI_CDSK Obj;
connect(Obj.penDrive,SIGNAL(clicked()),this,SLOT( Obj.caller()));
This code is in different class and from this class i want to execute slot of different class(UI_CDSK )
Here penDrive and caller belongs to function UI_CDSK class and the mentioned code is in other class
It's a little difficult without knowing the internals of UI_CDSK, but the correct syntax should be:
connect( Obj.penDrive, SIGNAL(clicked()), Obj, SLOT(caller()) );
So long as caller() is a public slot in UI_CDSK.
The connect method takes a pointer as receiver object, so if Obj isn't a pointer to a UI_CDSK object :
connect(Obj.pendrive, SIGNAL(clicked()), &Obj, SLOT(caller()));
Also this is probably already done (otherwise your compiler would have complained), but to use Qt signal slots mechanism, your UI_CDSK class must inherit from QObject.
It looks like the slot doesn't need to be public.
Related
I use observer-observable pattern in my program. Everything worked before I had to change the code a little. If to be exact I changed the inheritance of IObserver class - right now it inherits QObject:
class IObserver : public QObject
{
...
I did it because of only one thing - I need deleteLater() method to be used in an observer, so I would be able to call implementation of virtual function deinitialization() of IObserver. Thus I could standardize every IObserver message handler.
The problem is, I already inherited QObject (indirectly) in some Observer classes. Like MainForm or AboutDialog. Everything is going fine until I try to call "connect" method in AboutDialog class.
What can I do? I really need this deleteLater() method since I can't use "delete this" in IObserver code - this will call IObserver destructor, not the MainForm or Storage classes for instance.
Thank you.
I really need this deleteLater() method since I can't use "delete this" in IObserver code - this will call IObserver destructor, not the MainForm or Storage classes for instance.
If you make your destructor virtual (and you should!) it will call the derived destructor just fine. But a problem is that destructing a object while it is handling some signal/slot might cause problems with the event loop. You would have to be very careful with delete this anyway.
The problem is, I already inherited QObject (indirectly) in some Observer classes.
One way you could implement this, not sure if the best thought:
template <typename Derived>
class IObserver
{
// Just to be sure: (C++11)
static_assert(is_base_of<Derived, QObject>::value,
"must inherit from QObject when using IObserver");
void deleteMe()
{
QObject* thisObject = dynamic_cast<QObject*>(this);
// no need for check if thisObject equals null. static assert does this.
thisObject->deleteLater();
}
};
class MainForm : public IObserver<MainForm>, public QMainWindow
{
// ...
};
I believe this pattern is called static polymorphism.
Abandon inheritance of QObject for IObserver. Instead of that add such method to interface.
class IObserver : public QObject {
public:
QObject *object() const = 0;
...
Then if implementation of interface inherits the QObject you will return this pointer from object() method. If implementation of interface doesn't inherit QObject you can simply return pointer to some simple QObject which will handle destruction of this object.
Then you can simply connect deleteLater for object returned by this method.
Off topic
Use of interfaces for observing in Qt usually is obsolete, slots and signals do this job perfectly and this is more flexible approach.
My original code passed a QStringList from the signal to the slot and then returned a QList. Everything worked fine but I needed to change both the QStringList and QList into 2 different subclassed QObjects. Since then I have been receiving errors like "synthesized method first required here" or it simply crashes without any error message.
I understand that qt copies all arguments passed in a queued connection and a qobject cannot be copied. So instead of returning a qobject I thought I would create both qobjects prior to emitting the signal. Then I would pass references to each object, modify one of them in the slot function and void the return value. Unfortunately the app still crashes no matter how I code the signal and slot functions. How can I code the signal/slot functions and connect them to either pass both qobjects as arguments or return a qobject?
MyQObject1 obj1("a","b","c");
MyQObject2 obj2();
emit sendSignal(&obj1, &obj2);
// or
MyQObject2 obj2 = emit sendSignal(&obj1);
connect(someObj, SIGNAL(sendSignal(const QObject&)), this, SLOT(receiveSignal(const QObject&)));
The receiveSignal() function does not directly create or modify any qobject. It has to pass the qobjects to another function first which then either modifies obj2 or creates and returns it. Any code examples would be greatly appreciated.
Usually QObject is passed by pointer, not by reference (note that QObject cannot be copied and cannot be passed by value). QObject* is registered as a meta type by default. So creating a signal and a slot with QObject* argument is enough to get them work:
private slots:
void test_slot(QObject* object);
signals:
void test_signal(QObject* object);
Initialization:
connect(this, SIGNAL(test_signal(QObject*)), this, SLOT(test_slot(QObject*)));
Emitting:
QObject* object = new QObject();
emit test_signal(object);
Of course the signal and the slot could be in different classes.
I have a class called MainWindow and it initializes objects of GLWidget and clothWidget class, both aforementioned classes inherit QGLWidget class. Initialization in MainWindow class is like
glWidget = new GLWidget();
clWidgetf = new clothWidget();
and I have an object of GLWidget class declared in clothwidget.h. When I do
clwidgetf->gl = glwidget ( here gl is object of class GLWidget declared in ClothWidget class) in MainWindow
I get following errors
/usr/include/qt4/QtOpenGL/qgl.h:592: error: 'QGLWidget&
QGLWidget::operator=(const QGLWidget&)' is private
/home/arun/Desktop/garment/glwidget.h:8: error: within this context
The problem is you are (unintentionally) trying to copy the widget, and since it is QObject based it cannot be copied. In the "olden days" (until very recently) the only way to make that was to make the copy constructor private, which is exactly the error message you are getting. Double-check your code to make sure you are not passing as a value copy (as Riateche suggested in the comments).
If you want a reference then you have to initialize it with your object, you can not set it elsewhere, but most likely you want a pointer so you should pass pointer to your function and make your class member a pointer too, or take an adress of passet reference and still assign it to some pointer.
And you can't copy anything derived from QObject since constructors are private.
Like the title,why the "q_ptr" pointer is assigned to "this" pointer of QObject? in source code.
QObject::QObject(QObjectPrivate &dd, QObject *parent)
: d_ptr(&dd)
{
>>Q_D(QObject);
>>d_ptr->q_ptr = this;/*question*/
.......
Then,when use Q_Q() macro in source code like blow:
Q_Q(QWidget)
It will return the q pointer handled by the function q_fun():
QWidget*q_func() {return static_cast<QWidget*>(q_ptr);}
As all we know,static_castis not safe when cast from parent to child.
I am very frustrated about /*question*/ ,can any guy tell me the secret?Thanks!
d_ptr->q_ptr = this;/*question*/
This is where the private implementation object (PIMPL idiom) is told about the object it is working for/with (the non-private QObject). Here's a good link for info about Qt and d pointers (d_ptr).
Q_Q macro returns the pointer to the QObject, so you can emit signals from it (among other things). As for the static_cast bit, that is safe because the macro is defined differently for each class created by the Q_DECLARE_PRIVATE and Q_DECLARE_PUBLIC macros: the result being, static_cast is always casting to the correct type. Again, I recommend reading the link.
I am trying to create an event handler that executes a function when the page load is done in the QWebView, the syntax i'm using is as follows:
webview->connect(webview,SIGNAL(loadFinished(bool)),this,SLOT(Load_Done()));
This function is created and implemented in a class that i'm using other than the main class if this helps.
The problem is that i'm getting the following:
No such slot QObject::Load_Finished()
It should be QObject::connect(...) not webview->connect. The rest looks fine as long as Load_Done() is defined.
Edit:
To make sure that signals and slots work properly, you need to declare your class that way:
class Facebook: QObject{
Q_OBJECT
public:
// ...
public slots:
void Load_Done();
}
The signal and the slot have to have the same signature, e.g.:
connect(webview,SIGNAL(loadFinished(bool)),this,SLOT(Load_Done(bool)));
Of course, LoadDone(bool) needs to exist in "this" and be a slot :)