cannot call button signal from abstract class - c++

I want to call a function when a button click. the implementation of the button is in the abstract class. but when I compile I'm getting this error.
This is my .h file of the base class
#ifndef HOME_H
#define HOME_H
#include<QGraphicsScene>
#include <QGraphicsScene>
#include<QPushButton>
class home
{
Q_OBJECT
public:
home();
virtual void set_home_background()=0 ;
QGraphicsScene *scene3;
QPushButton *button3;
private slots:
virtual void startgame1();
};
#endif // HOME_H
This is the base class
#include "home.h"
#include<QGraphicsScene>
#include<QGraphicsProxyWidget>
#include "QMessageBox"
home::home()
{
}
void home::set_home_background()
{
button3 = new QPushButton;
QObject::connect(button3,SIGNAL(clicked()),this,SLOT(startgame1()));
QGraphicsProxyWidget *proxy = this->scene3->addWidget(button3);
button3->setAutoFillBackground(true);
button3->setIcon(QIcon(":/Images/ng.png"));
button3->setIconSize(QSize(131,41));
proxy->setPos(130,430);
scene3->addItem(proxy);
}
void home::startgame1()
{
QMessageBox q;
q.setText("");
q.exec();
}
I'm getting this error
C:\Users\User\Documents\breakout_final\home.cpp:16: error: no matching
function for call to 'QObject::connect(QPushButton*&, const char*,
home*, const char*)'
QObject::connect(button3,SIGNAL(clicked()),this,SLOT(startgame1()));
^

You have an error in your code: in order to use Qt signals and slots, you should inherit your class from QObject, Q_OBJECT declaration itself is not enough:
#include <QObject>
class home : public QObject
{
Q_OBJECT
public:
home();
virtual void set_home_background()=0 ;
QGraphicsScene *scene3;
QPushButton *button3;
private slots:
virtual void startgame1();
};

Related

setWindowState from QMainWindow from QWidget

I have a QMainWindow Application which also includes an QStackedWidget.
The pages of the QstackedWidget are promoted to ui widgets for example heating_widget.ui
If I use a button slot on my QMainWindow I can use this to get my application to fullscreen:
void SmartHome::on_fullscreen_on_clicked()
{
SmartHome::setWindowState(Qt::WindowFullScreen);
}
But how can I do this from a button which is in the heating_widget.cpp file?
Using:
void heating_widget::on_fullscreen_on_clicked()
{
SmartHome::setWindowState(Qt::WindowFullScreen);
}
obviously doesn't work and throws this error at me:
cannot call member function 'void
QWidget::setWindowState(Qt::WindowStates)' without object
SmartHome::setWindowState(Qt::WindowFullScreen);
I know this has something to do with parent() but I can't get it to work.
Do you have any idea?
My smarthome.h file:
#ifndef SMARTHOME_H
#define SMARTHOME_H
#include <QTime>
#include <QMainWindow>
namespace Ui {
class SmartHome;
}
class SmartHome : public QMainWindow
{
Q_OBJECT
public:
explicit SmartHome(QWidget *parent = 0);
~SmartHome();
private slots:
void on_Info_Button_clicked();
void on_News_Button_clicked();
void on_Heating_clicked();
void timerslot();
void on_Config_clicked();
void on_About_clicked();
public slots:
void setFullscreen();
private:
Ui::SmartHome *ui;
QTimer* myTimer;
};
#endif // SMARTHOME_H
My heating_widget.h :
#ifndef HEATING_WIDGET_H
#define HEATING_WIDGET_H
#include "smarthome.h"
#include <QWidget>
namespace Ui {
class heating_widget;
class SmartHome;
}
class heating_widget : public QWidget
{
Q_OBJECT
public:
explicit heating_widget(QWidget *parent = 0);
~heating_widget();
private slots:
void on_fullscreen_on_clicked();
private:
Ui::heating_widget *ui;
};
#endif // HEATING_WIDGET_H
and my heating.widget.cpp:
#include "heating_widget.h"
#include "ui_heating_widget.h"
#include "smarthome.h"
#include "iostream"
heating_widget::heating_widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::heating_widget)
{
ui->setupUi(this);
QObject::connect(ui->fullscreen_on, SIGNAL(clicked()), this , SLOT(SmartHome::setFullscreen()));
}
heating_widget::~heating_widget()
{
delete ui;
}
void heating_widget::on_fullscreen_on_clicked()
{
parentWidget()->setWindowState(Qt::WindowFullScreen);
std::cout<<"clicked"<<std::endl;
}
I would do it in the following way:
void heating_widget::on_fullscreen_on_clicked()
{
foreach(QWidget *widget, QApplication::topLevelWidgets()) {
if (auto mainWindow = qobject_cast<SmartHome *>(widget)) {
mainWindow->setWindowState(Qt::WindowFullScreen);
}
}
}
The idea is finding your main window among application top level widgets and change its state. This code can be called from anywhere in your application regardless of the windows hierarchy.

Qt connect between two classes not working

I have two classes: HoodPlanner and DrawRoad. Both classes inherit from QWidget and the the UI so I can access all UI elements in both classes.
Here's a snipped of both classes:
HoodPlanner:
#ifndef HOODPLANNER_H
#define HOODPLANNER_H
#include <ui_hoodplanner.h>
#include "drawroad.h"
#include <QtWidgets>
class HoodPlanner : public QWidget, private Ui::HoodPlanner
{
Q_OBJECT
private:
// (...)
public:
explicit HoodPlanner(QWidget * = 0);
// (...)
private slots:
// (...)
};
#endif // HOODPLANNER_H
DrawRoad:
#ifndef DRAWROAD_H
#define DRAWROAD_H
#include <ui_hoodplanner.h>
#include <QtWidgets>
class DrawRoad : public QWidget, private Ui::HoodPlanner
{
Q_OBJECT
private:
// (...)
public:
explicit DrawRoad(QWidget *parent = 0);
public slots:
void drawSC4Street();
};
#endif // DRAWROAD_H
In HoodPlanner I have a connect that will be emitted whenever the itemSelection changes in table_ts2. I have the slot stored in DrawRoad, but inserting a reference to the DrawRoad object in third position brings up errors.
HoodPlanner::HoodPlanner(QWidget *parent) : QWidget(parent)
{
setupUi(this);
// (...)
DrawRoad *drawRoad = new DrawRoad;
connect(table_ts2, SIGNAL(itemSelectionChanged()), &drawRoad, SLOT(drawSC4Street()));
}
Snipped from DrawRoad.cpp:
#include "drawroad.h"
DrawRoad::DrawRoad(QWidget *parent) : QWidget(parent)
{
}
void DrawRoad::drawSC4Street()
{
if(!table_ts2->selectionModel()->hasSelection()) return;
// (...)
}
And the following errors occur whenever I run the app:
hoodplanner.cpp:12: Fehler: no matching function for call to 'HoodPlanner::connect(QTableWidget*&, const char [24], DrawRoad**, const char [17])'
mingw492_32\include\QtCore\qobject.h:213: Fehler: no type named 'Object' in 'struct QtPrivate::FunctionPointer<const char*>'
(and lots of notes)
The errors don't help me at all and I've searched in several topics for a solution, but none of them had my problem.
Have you tried
HoodPlanner::HoodPlanner(QWidget *parent) : QWidget(parent)
{
setupUi(this);
// (...)
DrawRoad *drawRoad = new DrawRoad;
connect(table_ts2, SIGNAL(itemSelectionChanged()), drawRoad, SLOT(drawSC4Street()));
}
You declrared drawRoad as a pointer:
DrawRoad *drawRoad = new DrawRoad;
And then you pass its address to connect() with &drawRoad.
In this case you are passing a pointer to a pointer address. Try without the &

Subclassing QLabel and use it in QWidget class

When i try to put QLabel in QWidget class its not work properly (no hover event or click event only the label pixmap is show) only the last instance work properly, when not use set parent, it create in new window for each label but its work correctly
this gif show the problem:
https://media.giphy.com/media/3o7TKKmZSISGXN4Opq/giphy.gif
this is QLabel subclass header:
#include <QObject>
#include <QLabel>
class myLabel : public QLabel
{
Q_OBJECT
public:
myLabel();
protected:
void mousePressEvent(QMouseEvent *);
void enterEvent(QEvent *);
void leaveEvent(QEvent *);
signals :
void labelClicked();
void enterSignal();
void leaveEventSignal();
private:
};
this class to make a labelButton:
#include <QObject>
#include <QWidget>
#include "mylabel.h"
class labelButton : public QWidget
{
Q_OBJECT
public:
labelButton();
//some functions
private slots:
//slots
private:
//private member
};
and this the class that i want to use the labelButtons in:
#include <QWidget>
#include "labelbutton.h"
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
private:
Ui::Widget *ui;
labelButton *b_1, *b_2, *b_3;
};
here is widget.cpp:
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
b_1 = new labelButton;
b_1->setParent(this);
b_1->moveButton(70, 100);
//some functions to initialize the labelButton
b_1->show();
//-----------------------
b_2 = new labelButton;
b_2->setParent(this);
b_2->moveButton(70, 200);
//some functions to initialize the labelButton
b_2->show();
//-----------------------
b_3 = new labelButton;
b_3->setParent(this);
b_3->moveButton(70, 300);
//some functions to initialize the labelButton
b_3->show();
}
here its work, the problem was in passing the parent
i made a function that take a widget and set buttons parent from the function value
b_1 = new labelButton;
//b_1->setParent(this);
b_1->setParentFunc(this);
b_1->moveButton(70, 100);
//some functions to initialize the labelButton
// b_1->show();
in labelButton:
void labelButton::setParentFunc(QWidget *p)
{
myParent = p;
}
mLabel_1->setParent(myParent); // myParent instead of this

Cant declare a QWidget because virtual functions are pure

I'm trying to make use of interfaces in Qt/C++, but I keep getting a compile error which makes no sense to me, because I have implemented the virtual functions in the derived class. So I was hoping for some help :) Oh yeah, and the compile error is "cannot declare variable 'w' to be of abstract type 'Widget' because the following virtual functions are pure within 'Widget': startGame(), getBoard(), gameFinished().
Main.cpp
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
ADTType.h
#ifndef ADTTYPE_H
#define ADTTYPE_H
class ADTType
{
public:
virtual void startGame() = 0;
virtual void getBoard() = 0;
virtual void gameFinished() = 0;
virtual ~ADTType() {}
};
Q_DECLARE_INTERFACE(ADTType, "ADTType")
#endif // ADTTYPE_H
Widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QSignalMapper>
#include <QHBoxLayout>
#include <QPushButton>
#include "ADTType.h"
class Widget : public QWidget,
public ADTType
{
Q_OBJECT
Q_INTERFACES(ADTType)
public:
explicit Widget(QWidget *parent = 0);
~Widget();
private:
QHBoxLayout * mainLayout;
QPushButton * startButton;
QPushButton * buttons[10];
QSignalMapper * map;
};
#endif // WIDGET_H
Widget.cpp
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent) :
QWidget(parent)
{}
Widget::~Widget()
{}
void Widget::startGame() {
for (int i = 0; i < 10; i++) {
buttons[i]->setStyleSheet("QPushButton {background-color: normal}");
}
setButtons(true);
startButton->setDisabled(true);
}
void Widget::getBoard() {
bool * cells = game->getCells();
for (int i = 0; i < 10; i++) {
if (!cells[i]) {
buttons[i]->setStyleSheet("QPushButton {background-color: red}");
buttons[i]->setEnabled(false);
}
}
}
void Widget::gameFinished() {
int answer = game->getAnswer();
buttons[answer]->setStyleSheet("QPushButton {background-color: green}");
setButtons(false);
game->reset();
QMessageBox::information(this,tr("Finito"),tr("You found it."),
QMessageBox::Ok);
startButton->setEnabled(true);
}
class Widget : public QWidget,
public ADTType
So Widget inherits from the abstract class ADTType. However, you don't declare the overrides (startGame() etc) in your Widget class, but you only define them in the Widget.cpp file. You also need to declare them in the Widget.h class header
// need these declarations inside the class Widget in Widget.h
virtual void startGame();
virtual void getBoard();
virtual void gameFinished();
Minimal example here.
You derived ADTType abstract class from the Widget so you need to override pure virtual functions in the Widget class otherwise it also will become abstract.
class Widget : public QWidget,
public ADTType
{
...
void startGame() { ... }
void getBoard() { ... }
void gameFinished() { ... }
};

QWidget inherit from custom QWidget

In Qt C++, is it possible to create a custom QWidget and then reuse this custom QWidget for all QWidget (that inherit all from the custom QWidget) of the project?
Maybe I have misunderstood the question, but you can just create your custom QWidget, then use it everywhere.
class derivedQWidget : public QWidget
{
Q_OBJECT
derivedQWidget();
virtual ~derivedQWidget();
}
class myWidget : public derivedQWidget
{
...
}
class myWidget2 : public derivedQWidget
{
...
}
If the question is: Can we reimplement QWidget?, no you can't.
i have solved in this mode:
the first class, Widget.h:
#ifndef WIDGET_H
#define WIDGET_H
#include <QPushButton>
#include <QMouseEvent>
#include <QWidget>
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = 0);
virtual ~Widget();
QPushButton *getBtn() const;
void setBtn(QPushButton *value);
protected:
void mousePressEvent(QMouseEvent *evt);
void mouseMoveEvent(QMouseEvent *evt);
private:
Ui::Widget *ui;
QPushButton *btn;
QPoint oldPos;
};
and the second class widExt.h, that inherit from Widget:
#ifndef WIDEXT_H
#define WIDEXT_H
#include "widget.h"
namespace Ui {
class widExt;
}
class widExt : public Widget
{
public:
widExt();
private slots:
void on_dial_2_actionTriggered(int action);
private:
Ui::widExt *ui;
};
#endif // WIDEXT_H
with the relative widExt.cpp:
#include "widext.h"
#include "ui_widext.h"
widExt::widExt() : ui(new Ui::widExt)
{
ui->setupUi(this);
}
void widExt::on_dial_2_actionTriggered(int action)
{
}
in this mode, i inherit all from the first class and i can customize other classes independently.