Templates class connect - c++

mainwindow.cpp
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
Form* form = new Form;
Form1* form1 = new Form1;
obj = new MyObj<Form>(form);
emit mySig(form1);
emit mySig(form);
}
myobject.h
#include <QObject>
#include "form.h"
#include "form1.h"
class MyObjBase : public QObject
{
Q_OBJECT
public:
MyObjBase() {}
private slots:
virtual void mySlot(Form* f) = 0;
virtual void mySlot(Form1* f) = 0;
signals:
void mySig(Form* f);
void mySig(Form1* f);
};
template <typename T>
class MyObj : public MyObjBase
{
public:
MyObj(T* obj) : MyObjBase()
{
this->obj = obj;
connect(this,SIGNAL(mySig(T*)),this,SLOT(mySlot(Form*)));
}
T* obj = NULL;
void mySlot(Form* f) {
qDebug() << Q_FUNC_INFO;
}
void mySlot(Form1* f) {
qDebug() << Q_FUNC_INFO;
}
void emitSig() {
emit mySig(obj);
}
};
Why is the connect not working? I thought when i specialize my template class via <> when i initialize it, that the compiler creates new code for that class where T = Form. Then the connect should work in my opinion :D
Get a generic connect like that working would make my code shorter.
It compiles fine but the output is:
QObject::connect: No such signal MyObjBase::mySig(T*) in
..\overload_signals\myobj.h:30
thank you for helping me

Related

no member function declared in class 'MainWindow'

I'm trying to make a fake FBI program for a prank, but it's not as easy as I expected it to be.
This is my code.
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
ui->trackConnButton->setEnabled(false);
}
void MainWindow::on_confirmButton_clicked() {
if (ui->usernameText == "name" && ui->passwordText == "password") {
ui->resullabel->setText("Password accepted.");
ui->trackConnButton->setEnabled(true);
} else {
ui->resullabel->setText("Password denied.");
}
}
MainWindow::~MainWindow()
{
delete ui;
}
I get this error:
D:\Qt-Projekte\test3\mainwindow.cpp:12: Fehler: no 'void MainWindow::on_confirmButton_clicked()' member function declared in class 'MainWindow'
void MainWindow::on_confirmButton_clicked() {
^
My question is now: how to fix it?
Thanks in advance.
my mainwindow.h:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
All member functions of a class must contain a "declaration" and a "definition".
For example:
struct Foo {
// Declarations
void foo() const;
int bar(int x);
};
// Definitions
void Foo::foo() const {
std::cout << "foo" << std::endl;
}
int Foo::bar(int x) {
return x + 1;
}
(Note that if you define a function inline in a class, it counts as both definition and declaration):
struct Foo {
// Declaration AND definition
void foo() const {
std::cout << "foo inline" << std::endl;
}
};
So in your case, you must declare the on_confirmButton_clicked function inside the definition of class MainWindow.

cannot access staticmetaobject

I cannot access staticmetaobject and I dont know why. I would need some help.
Here is the code
The two errors are:
staticMetaObject is not a member of MainWIndow*
I feel like it has something to do with the list, but I'm not sure.
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "form.h"
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
Form<MainWindow*>* form;
private slots:
void on_pushButton_clicked();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
/*qDebug() << MainWindow::staticMetaObject.className();
if (QString(MainWindow::staticMetaObject.className()) == QString("MainWindow")) {
qDebug() << "test";
}*/
form = new Form<MainWindow*>(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_pushButton_clicked()
{
form->myFunc();
}
form.h
#ifndef FORM_H
#define FORM_H
#include <QObject>
#include <QDebug>
class FormBase : public QObject
{
Q_OBJECT
public:
FormBase() {}
};
template <typename T>
class Form : public FormBase, public QList<T>
{
public:
Form(T a)
{
QList<T>::append(a);
}
void myFunc()
{
qDebug() << T::staticMetaObject.className();
}
};
#endif // FORM_H
You are getting you types confused.
You want T to be MainWindow so that you can do
T::staticMetaObject.className()
That means you want a QList<T*>. You derive from that so you can just call
append(a);
The following code compiles fine:
class FormBase : public QObject
{
Q_OBJECT
public:
FormBase() {}
};
template <typename T>
class Form : public FormBase, public QList<T*>
{
public:
Form( T* a )
{
append( a );
}
void myFunc()
{
qDebug() << T::staticMetaObject.className();
}
};
class MainWindow:
public QMainWindow
{
MainWindow()
{
form = new Form<MainWindow>( this );
}
FormBase* form;
};

display is not showing in text box from other class in qt

I have made made a DDisplay class to display my data on gui text box but I have some strange situation, when I call the function from mainwindow class it is working fine but when I try to call the same function from other class it is not working. below is the small code my program
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <ddisplay.h>
#include <QMainWindow>
#include "test.h"
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
DDisplay b;
Test c;
private slots:
void display(const QString &a);
void on_pushButton_clicked();
private:
Ui::MainWindow *ui;
};
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
QObject::connect(&b,SIGNAL(display(QString)),this,SLOT(display(QString)));
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::display(const QString &a){
ui->textBrowser->setText(a);
}
void MainWindow::on_pushButton_clicked()
{
b.printf("hello"); //this function working fine
//c.printf("lllll"); //not working
}
test.h
#ifndef TEST_H
#define TEST_H
#include <QString>
#include <ddisplay.h>
class Test
{
public:
Test();
void printf(const QString &a);
DDisplay b;
};
test.cpp
#include "test.h"
Test::Test()
{
}
void Test::printf(const QString &a){
b.printf(a);
}
ddisplay.h
#include
class DDisplay : public QObject
{
Q_OBJECT
public:
explicit DDisplay(QObject *parent = 0);
void printf(const QString &a);
QString b;
signals:
void display(const QString &a);
public slots:
};
ddisplay.cpp
#include "ddisplay.h"
DDisplay::DDisplay(QObject *parent) :
QObject(parent)
{
}
void DDisplay::printf(const QString &a)
{
b+=a;
emit display(b);
}
c.printf("lllll"); //not working
It's not working because you don't have a connect for this object. DDisplay in Test class is a dfferent instance than that in a MainWindow.
One possible solution for your question in comments below is to connect DDisplay's signal and MainWindow's slot either in main.cpp or in specialized initialization class.

Dynamic cast in class hierarchy with templates

in my project if I define base class Base_Dialog as non template and then try to assign 'caller' in already_exists_ it works in the way expected but if I make Base_Dialog as a template class then the algorithm 'already_exists_' (unchanged) will not work and caller will not change (this is especially intriguing that the algorithm is unchanged and yet once works and other time it doesn't):
//This is minimal example (I know it's somewhat longer than usual but in order to show what I mean it needs to be this length)
MAIN_DIALOG_HPP
#ifndef MAIN_DIALOG_HPP
#define MAIN_DIALOG_HPP
#include <QSet>
#include <QtDebug>
#include "Base_Dialog.hpp"
#include "ui_Main_Dialog.h"
#include "_1Dialog.hpp"
#include "_2Dialog.hpp"
/*The following approach will not work*/
class Main_Dialog : public Base_Dialog<Ui::Main_Dialog>
{
/*but if I would do as below (changing Base_Dialog to non-template) it will work:*/
//class Main_Dialog : public QDialog, private Ui::Main_Dialog, public Base_Dialog
Q_OBJECT
QSet<QDialog*>* dialogs_;
private:
template<class Dialog,class Caller>
bool already_created_(Caller*const&, QDialog*& already_exists);
template<class Dialog,class Caller, class Parent>
QDialog* create_(Caller*const&,Parent*const&);
public:
explicit Main_Dialog(QWidget *parent = 0);
template<class Dialog,class Caller>
QDialog* get_dialog(Caller*const& caller);
public slots:
void _1clicked()
{
this->hide();
get_dialog<_1Dialog>(this)->show();
}
void _2clicked()
{
this->hide();
get_dialog<_2Dialog>(this)->show();
}
};
template<class Dialog,class Caller>
bool Main_Dialog::already_created_(Caller*const& caller,QDialog*& already_exists)
{/*the already_exists is introduced here in order to remove repetions of code and
searching*/
auto beg = dialogs_->begin();
auto end = dialogs_->end();
while(beg != end)
{
if(dynamic_cast<Dialog*>(*beg))
{
already_exists = *beg;
static_cast<Base_Dialog*>(already_exists)->set_caller(caller);
return true;
}
++beg;
}
return false;
}
template<class Dialog,class Caller, class Parent>
QDialog* Main_Dialog::create_(Caller *const&caller, Parent *const&parent)
{
return (*dialogs_->insert(new Dialog(this,caller,parent)));
}
template<class Dialog,class Caller>
QDialog* Main_Dialog::get_dialog(Caller *const&caller)
{
QDialog* already_exists = nullptr;
if (already_created_<Dialog>(caller,already_exists))
{
return already_exists;
}
else
{
return create_<Dialog>(caller,this);
}
}
Main_Dialog::Main_Dialog(QWidget *parent) :
Base_Dialog<Ui::Main_Dialog>(this,this,parent),dialogs_(new QSet<QDialog*>)
{
setupUi(this);
}
#endif // MAIN_DIALOG_HPP
BASE_DIALOG_HPP
#ifndef BASE_DIALOG_HPP
#define BASE_DIALOG_HPP
#include <QDialog>
#include <QString>
class Main_Dialog;
template<class Ui_Dialog>
class Base_Dialog : public QDialog, protected Ui_Dialog
{
// Q_OBJECT //no signals/slots
protected:
Main_Dialog* main_dlg_;
QDialog* caller_;
public:
Base_Dialog(Main_Dialog *const &main_dlg, QDialog *const&caller, QWidget *parent = nullptr);
QDialog* set_caller(QDialog *const&);
QDialog* clear_caller();
Main_Dialog* clear_main_dlg();
};
/*----------------*/
//#include "Main_Dialog.hpp"
template<class Ui_Dialog>
Base_Dialog<Ui_Dialog>::Base_Dialog(Main_Dialog *const&main_dlg,QDialog *const&caller, QWidget *parent):
QDialog(parent),
main_dlg_(main_dlg),
caller_(caller)
{
//setupUi(this);
}
#include <QtDebug>
template<class Ui_Dialog>
QDialog* Base_Dialog<Ui_Dialog>::set_caller(QDialog *const&new_caller)
{
QDialog* old_caller = caller_;
caller_ = new_caller;
return old_caller;
}
#endif
_1DIALOG_HPP
#ifndef _1DIALOG_HPP
#define _1DIALOG_HPP
#include "Base_Dialog.hpp"
#include "ui__1Dialog.h"
class Main_Dialog;
class _1Dialog : public Base_Dialog<Ui::_1Dialog>
{
Q_OBJECT
public:
explicit _1Dialog(Main_Dialog* main_dlg, QDialog*caller, QWidget *parent = 0);
private slots:
void _2clicked();
void caller_clicked();
void main_clicked();
};
#endif // _1DIALOG_HPP
_1Dialog cpp
//_1Dialog cpp
#include "_1Dialog.hpp"
#include "_2Dialog.hpp"
#include "Main_Dialog.hpp"
_1Dialog::_1Dialog(Main_Dialog* main_dlg, QDialog*caller, QWidget *parent) :
Base_Dialog<Ui::_1Dialog>(main_dlg,caller,parent)
{
setupUi(this);
}
void _1Dialog::_2clicked()
{
this->hide();
main_dlg_->get_dialog<_2Dialog>(this)->show();
}
void _1Dialog::caller_clicked()
{
this->hide();
caller_->show();
}
void _1Dialog::main_clicked()
{
this->hide();
main_dlg_->show();
}
_2DIALOG_HPP
#ifndef _2DIALOG_HPP
#define _2DIALOG_HPP
#include "Base_Dialog.hpp"
#include "ui__2Dialog.h"
class Main_Dialog;
class _2Dialog : public Base_Dialog<Ui::_2Dialog>//,private Ui::_2Dialog
{
Q_OBJECT
private:
public:
explicit _2Dialog(Main_Dialog* main_dlg, QDialog*caller, QWidget *parent = 0);
private slots:
void _1clicked();
void caller_clicked();
void main_clicked();
};
#endif // _2DIALOG_HPP
_2Dialog cpp
//_2Dialog cpp
#include "_2Dialog.hpp"
#include "_1Dialog.hpp"
#include "Main_Dialog.hpp"
_2Dialog::_2Dialog(Main_Dialog* main_dlg, QDialog*caller, QWidget *parent) :
Base_Dialog<Ui::_2Dialog>(main_dlg,caller,parent)
{
setupUi(this);
}
void _2Dialog::_1clicked()
{
this->hide();
main_dlg_->get_dialog<_1Dialog>(this)->show();
}
void _2Dialog::caller_clicked()
{
this->hide();
caller_->show();
}
void _2Dialog::main_clicked()
{
this->hide();
main_dlg_->show();
}
Why is this behavior? Algorithm is unchanged and yet once it assigns correctly and the other time it doesn't?
In already_exists_ change line:
static_cast<Base_Dialog*>(already_exists)->set_caller(caller);
to:
static_cast<Dialog*>(already_exists)->set_caller(caller);
and add virtual inheritance for QDialog in Base_Dialog
#sehe, I want to thank you for pointing me into right direction, which allow me to resolve this problem. Great thanks, +1;

"Cannot" move pointer

In my code I have:
template<class Ui_Dialog>
QDialog* Base_Dialog<Ui_Dialog>::set_caller(QDialog *new_caller)
{
QDialog* old_caller = caller_;
caller_ = new_caller;//Here I'm trying to set this to new caller
return old_caller;
}
but after setting the caller to new caller and exiting from this fnc, when I call caller I'm still getting the old caller instead of new one, as if no changes were made. Why?
EDIT:
//caller is defined in a following way:
class Main_Dialog : public Base_Dialog<Ui::Main_Dialog> {};
EDIT 2:
The interesting thing is that if instead of public Base_Dialog I alter Base_Dialog to non-template and define Main_Dialog as:
class Main_Dialog : public Base_Dialog, private Ui::Main_Dialog {};
Then it works as intended. Why?!
EDIT 3:
class Main_Dialog;
template<class Ui_Dialog>
class Base_Dialog : public QDialog, protected Ui_Dialog
{
// Q_OBJECT //no signals/slots
protected:
Main_Dialog* main_dlg_;
QDialog* caller_;
public:
Base_Dialog(Main_Dialog *main_dlg, QDialog *caller, QWidget *parent = nullptr);
QDialog* set_caller(QDialog *);
QDialog* clear_caller();
Main_Dialog* clear_main_dlg();
};
/*----------------*/
#include "Main_Dialog.hpp"
template<class Ui_Dialog>
Base_Dialog<Ui_Dialog>::Base_Dialog(Main_Dialog *main_dlg,QDialog *caller, QWidget *parent):
QDialog(parent),
main_dlg_(main_dlg),
caller_(caller)
{
//setupUi(this);
}
#include <QtDebug>
template<class Ui_Dialog>
QDialog* Base_Dialog<Ui_Dialog>::set_caller(QDialog *new_caller)
{
QDialog* old_caller = caller_;
caller_ = new_caller;
return old_caller;
}
#include "_1Dialog.hpp"
#include "_2Dialog.hpp"
class Main_Dialog : public Base_Dialog<Ui::Main_Dialog>
{
Q_OBJECT
QSet<QDialog*>* dialogs_;
private:
template<class Dialog,class Caller>
bool already_created_(Caller*&, QDialog*& already_exists)const;
template<class Dialog,class Caller, class Parent>
QDialog* create_(Caller*,Parent*);
/*template<class Dialog>
void show_();*/
/* template<class Dialog,class Caller>
QDialog* find_(Caller*)const;*/
public:
explicit Main_Dialog(QWidget *parent = 0);
template<class Dialog,class Caller>
QDialog* get_dialog(Caller*& caller);
public slots:
void _1clicked();
void _2clicked();
};
template<class Dialog,class Caller>
bool Main_Dialog::already_created_(Caller*& caller,QDialog*& already_exists)const
{/*the already_exists is introduced here in order to remove repetions of code and
searching*/
auto beg = dialogs_->begin();
auto end = dialogs_->end();
while(beg != end)
{
if(dynamic_cast<Dialog*>(*beg))
{
already_exists = *beg;
static_cast<Base_Dialog*>(already_exists)->set_caller(caller);
return true;
}
++beg;
}
return false;
}
template<class Dialog,class Caller, class Parent>
QDialog* Main_Dialog::create_(Caller *caller, Parent *parent)
{
return (*dialogs_->insert(new Dialog(this,caller,parent)));
}
template<class Dialog,class Caller>
QDialog* Main_Dialog::get_dialog(Caller *&caller)
{
QDialog* already_exists = nullptr;
if (already_created_<Dialog>(caller,already_exists))
{
return already_exists;
}
else
{
return create_<Dialog>(caller,this);
}
#include "Base_Dialog.hpp"
#include "ui__1Dialog.h"
class Main_Dialog;
class _1Dialog : public Base_Dialog<Ui::_1Dialog>
{
Q_OBJECT
public:
explicit _1Dialog(Main_Dialog* main_dlg, QDialog*caller, QWidget *parent = 0);
private slots:
void _2clicked();
void caller_clicked();
void main_clicked();
};
#endif // _1DIALOG_HPP
#include "_1Dialog.hpp"
#include "_2Dialog.hpp"
#include "Main_Dialog.hpp"
_1Dialog::_1Dialog(Main_Dialog* main_dlg, QDialog*caller, QWidget *parent) :
Base_Dialog(main_dlg,caller,parent)
{
setupUi(this);
}
void _1Dialog::_2clicked()
{
this->hide();
main_dlg_->get_dialog<_2Dialog>(this)->show();
}
void _1Dialog::caller_clicked()
{
this->hide();
caller_->show();
}
void _1Dialog::main_clicked()
{
this->hide();
main_dlg_->show();
}
}
#endif // MAIN_DIALOG_HPP
I think your problem not in set_caller. Next works for me:
#include <iostream>
using namespace std;
class QDialog {
int i;
public:
QDialog() : i(0) {}
QDialog(int i) : i(i) {}
void me() { cout << i << endl; }
};
namespace UI {
class Main_Dialog {}; // EDITED
}
template<class Ui_Dialog>
class Base_Dialog : public QDialog, protected Ui_Dialog
{
QDialog* caller_;
public:
QDialog* set_caller(QDialog *new_caller);
QDialog* get_caller() {return caller_; } ;
};
template<class Ui_Dialog>
QDialog* Base_Dialog< Ui_Dialog>::set_caller(QDialog *new_caller)
{
QDialog* old_caller = caller_;
caller_ = new_caller;//Here I'm trying to set this to new caller
return old_caller;
}
class Main_Dialog : public Base_Dialog<UI::Main_Dialog> {
public:
};
int main()
{
QDialog q1(1);
QDialog q2(2);
Main_Dialog md;
md.set_caller(&q1);
md.get_caller()->me();
md.set_caller(&q2);
md.get_caller()->me();
return 0;
}