QML: How to call method from a C++ subclass? - c++

I have two C++ classes (TrafficLight and Light). Light is a child of TrafficLight. QML can see everything from TrafficLight and nothing from Light, for example...I get the following error when I try to access a method from Light like TrafficLight.get_light(0).get_color()
TypeError: Cannot call method 'get_color' of undefined
I exposed my parent class (TrafficLight) to qml (see main below). I assumed it would expose the subclass inside it, as well...but apparently not.
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include "traffic_light.h"
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
Traffic_Light traffic_light;
engine.rootContext()->setContextProperty("TrafficLight", &traffic_light);
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
return app.exec();
}
My question is how would I expose the subclass? I can't just create an instance of Light and expose it the same way I did TrafficLight. Reason being is it won't be the same Light that's inside the TrafficLight. :(
light.h
#ifndef LIGHT_H
#define LIGHT_H
#include <QDebug>
#include <QObject>
enum Color
{
RED = 0,
YELLOW,
GREEN
};
class Light : public QObject{
Q_OBJECT
public:
Light();
public slots:
void set_color(Color color);
int get_color();
void set_light(bool is_on);
bool get_light();
private:
Color m_color;
bool m_light_on;
};
#endif // LIGHT_H
traffic_light.h
#ifndef TRAFFIC_LIGHT_H
#define TRAFFIC_LIGHT_H
#include <QDebug>
#include <QObject>
#include <QTimer>
#include "light.h"
class Traffic_Light : public QObject
{
Q_OBJECT
public:
Traffic_Light();
public slots:
Light &get_light(int index);
void toggle_light(int index);
private:
Light m_light[3];
};
#endif // TRAFFIC_LIGHT_H

Related

Add custom QWidget to another QWidget

I'm trying to add an objects (that inherits from QWidget) as a child to another QWidget as shown below, it works perfectly with another normal QWidget instance but not with my custom class, any idea why ?
fenetre.h
#ifndef FENETRE_H
#define FENETRE_H
#include <QWidget>
#include <QMouseEvent>
class Fenetre : public QWidget
{
Q_OBJECT
public:
Fenetre();
};
#endif // FENETRE_H
fenetre.cpp
#include "fenetre.h"
Fenetre::Fenetre() : QWidget()
{
}
main.cpp
#include <iostream>
#include <QApplication>
#include <QWidget>
#include "fenetre.h"
int main(int argc, char *argv[])
{
QApplication app(argc,argv);
QWidget window;
window.setFixedSize(800,600);
//This appears
QWidget rec1;
rec1.setParent(&window);
rec1.setFixedSize(100,100);
rec1.move(400,200);
rec1.setStyleSheet("background-color: red");
//This one not
Fenetre rec2;
rec2.setParent(&window);
rec2.setFixedSize(100,100);
rec2.move(200,200);
rec2.setStyleSheet("background-color: green");
window.show();
return app.exec();
}
PS: I did research on the platform, but the majority of the answers speak of the use of a layout. Thank you !
you miss the parent:
//header .h
class Fenetre : public QWidget
{
Q_OBJECT
public:
Fenetre(QWidget *parent = 0);
};
//source .cpp
Fenetre::Fenetre(QWidget *parent) : QWidget(parent)
{
}

How to connect a button from ui-file class to slots from other classes?

I have 3 classes.
class with a mainwindow which comes from the designer(ui-file)
class wich will manage database stuff like inserts
controller class. I want to extend the whole thing to networkcommunication later.
My problem:
I want to connect a simple QPushButton ui->addbutton from the window class with a slot addEntry from the databaseclass, but I get this error :
ERROR: no matching function for call to
'generalControler::connect(QPushButton*, const char*, dbmanager*&,
const char*)'
mydb, SLOT(addEntry()));
//no difference with &mydb or *mydb
MainWindow(0x13f57988, name = "MainWindow") QPushButton(0x13f5f3e0, name = "addButton")
MainWindow(0x13f57988, name = "MainWindow") 0x13f5f3e0//<--?????
//<=Here u see the adresses printed with Qdebug(). top: mainwindowclass. bot: generalcontrolerclass
//why there is missing information after returning the adress of a 'ui->addButton' to another class? Is this maybe the problem?
main.cpp
#include <QApplication>
#include "generalcontroler.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
generalControler controler;
return a.exec();
}
generalcontroler.h
#ifndef GENERALCONTROLER_H
#define GENERALCONTROLER_H
#include <QApplication>
#include "mainwindow.h"
#include "dbmanager.h"
class generalControler : public QObject
{
Q_OBJECT
public:
generalControler();
};
#endif // GENERALCONTROLER_H
generalcontroler.cpp
#include "generalcontroler.h"
#include <QDebug>
generalControler::generalControler(){
MainWindow* window = new MainWindow;
window->show();
dbmanager* mydb= new dbmanager("path_to_my_database.db", window);
mydb->addEntry();
qDebug()<<window->getThis()<<window->getcloseButton();
connect(window->getaddButton(), SIGNAL(clicked()),
mydb, SLOT(addEntry()));
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QMessageBox>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
QPushButton* getaddButton();
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);
}
QPushButton* MainWindow::getaddButton()
{
return ui->addButton;
}
dbmanager.h
#ifndef DBMANAGER_H
#define DBMANAGER_H
#include <QSqlDatabase>
#include <QDebug>
#include "mainwindow.h"
class dbmanager: public QObject{
Q_OBJECT
public:
dbmanager(const QString& path);
public slots:
void addEntry();
private:
QSqlDatabase mydatabase;
};
#endif // DBMANAGER_H
dbmanager.cpp
#include "dbmanager.h"
dbmanager::dbmanager(const QString& path)
{
mydatabase = QSqlDatabase::addDatabase("QSQLITE");
mydatabase.setDatabaseName(path);
if (!mydatabase.open())
{
qDebug() << "Error: connection fail";
}
else
{
qDebug() << "Database: connection ok";
}
}
void dbmanager::addEntry()
{
qDebug()<<"addEntry success";
}
I was searching for 6 hours but I never saw such an example with 2 classes, a controler and an ui-file. Could anyone help me?
The connect looks good to me. Try if #include <QPushButton> in generalcontroler.cpp helps. If the compiler knows about QPushButton only by forward-declaration, it doesn't know that it's a QObject and thus the connect() signatures (with QObject* in it) don't match.

C++ accessing object, QT

I'd appreciate it, when someone could help me. I am not used to C++. I am new to it.
My problem: I want to make an object "player" usable for another class. I don't get how to archive this.
main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
mainwindow.h
#include <QMainWindow>
#include <QMediaPlayer>
#include <QDebug>
#include "Leap.h"
#include <leapmotionlistener.h>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
QMediaPlayer* player;
private slots:
....
private:
Ui::MainWindow *ui;
void initialize();
Controller controller;
LeapMotionListener leapMotionListener;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QSound>
#include <iostream>
#include <QfileDialog>
using namespace std;
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
player = new QMediaPlayer(this);
connect(player, &QMediaPlayer::positionChanged, this, &MainWindow::on_positionChanged);
connect(player, &QMediaPlayer::durationChanged, this, &MainWindow::on_durationChanged);
initialize();
}
QString path;
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::initialize(){
controller.addListener(leapMotionListener);
leapMotionListener.setPlayer(player);
controller.setPolicy(Leap::Controller::POLICY_BACKGROUND_FRAMES);
}
...
leapmotionlistener.h
#ifndef LEAPMOTIONLISTENER
#define LEAPMOTIONLISTENER
#include <iostream>
#include <cstring>
#include "Leap.h"
#include <QFile>
#include <QAudioOutput>
#include <QMediaPlayer>
using namespace Leap;
class LeapMotionListener : public Listener {
public:
LeapMotionListener();
void setPlayer(QMediaPlayer&);
//... some more methods
private:
QMediaPlayer player;
};
#endif // LEAPMOTIONLISTENER
leapmotionlistener.cpp
//calls the player object in one method like the following
player.stop();
My main questions are: What am I doing wrong while referencing and instantiating? And how can leapmotionlistener access the same player object (I want to influence the audio)?
I get the Error:
MusicPlayer\mainwindow.cpp:32: Error: C2664: 'void LeapMotionListener::setPlayer(QMediaPlayer &)' : converting from argument 1 'QMediaPlayer *' in 'QMediaPlayer &' not possible
This little project is downloadable for a quick view with the following link:
https://www.dropbox.com/s/igr7ywnvicdlxxd/MusicPlayer.zip?dl=0
Thanks in advance!
All you need to do is
leapMotionListener.setPlayer(*player);
An lvalue reference binds to an object, not to the pointer to the object. In order to get the object from a pointer to it, you need to dereference the pointer using the *.
Among other problems, the QMediaPlayer you're trying to pass to setPlayer is a pointer, not a reference to an object.
You can either instantiate your player object like this:
QMediaPlayer player;
Or you can change your setPlayer function signature to this:
void setPlayer(QMediaPlayer* mplayer);
If you update your function signature, you'll also need fix other function signatures and leave the ampersands out of your connect() statements when you're referencing the player.
the following worked now:
in MainWindow.h:
public:
QMediaPlayer* player;
in MainWindow.cpp:
player = new QMediaPlayer(this);
leapMotionListener.setPlayer(player);
controller.addListener(leapMotionListener);
in LeapMotionListener.h:
private:
QMediaPlayer *player;
public:
void setPlayer(QMediaPlayer *mplayer);
in LeapMotionListener.cpp:
LeapMotionListener::LeapMotionListener()
: player(0)
{}
void LeapMotionListener::setPlayer(QMediaPlayer *mplayer){
player = mplayer;
}

QT connect crash using signal accepted

I have a problem with my Qt code. I wanted to write an program which are taking a coordinates of point and then that point is drawing in point with that coordinates. My program doesn't have any errors or warnings when i built it but it's crashing at start(MainWindow doesn't show). This is my code:
main.cpp
#include < QApplication >
#include "mainwindow.h"
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
MainWindow win;
win.show();
return app.exec();
}
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QWidget>
#include <QAction>
#include <QToolBar>
#include <QTextCodec>
#include <QObject>
#include <QDialog>
#include <QLineEdit>
#include <QPushButton>
#include <QString>
#include "addpoint.h"
class MainWindow: public QMainWindow
{
Q_OBJECT
private:
QToolBar *AddToolbar;
QAction *AddPointAction;
AddPoint *AddPointDialog;
QLineEdit *x;
public:
MainWindow();
void createToolbar();
void createActionAdd();
signals:
public slots:
void PointClicked();
void DialogAccepted();
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
MainWindow::MainWindow()
{
QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8"));
createActionAdd();
createToolbar();
connect(AddPointAction, SIGNAL(triggered(bool)), this, SLOT(PointClicked()));
connect(AddPointDialog, SIGNAL(accepted()), this, SLOT(DialogAccepted()));
setMinimumSize(480, 320);
}
/**/
void MainWindow::createToolbar()
{
AddToolbar = new QToolBar;
AddToolbar->addAction(AddPointAction);
addToolBar(AddToolbar);
}
/**/
void MainWindow::createActionAdd()
{
AddPointAction = new QAction("Add Road", this);
x = new QLineEdit(this);
x->setFixedSize(100, 30);
x->move(100, 100);
}
/**/
void MainWindow::PointClicked()
{
AddPointDialog = new AddPoint(this);
AddPointDialog->setModal(true);
AddPointDialog->exec();
}
/**/
void MainWindow::DialogAccepted()
{
x->setText("abc");
}
addpoint.h
#ifndef ADDPOINT_H
#define ADDPOINT_H
#include <QWidget>
#include <QTextCodec>
#include <QDialog>
#include <QObject>
#include <QLabel>
#include <QLineEdit>
#include <QPushButton>
#include <QString>
class AddPoint : public QDialog
{
Q_OBJECT
private:
QLabel *XpointL;
QLineEdit *XPoint;
QPushButton *OKButton;
public:
AddPoint(QWidget *parent);
void createButton();
signals:
public slots:
};
#endif // ADDPOINT_H
addpoint.cpp
#include "addpoint.h"
AddPoint::AddPoint(QWidget *parent) :QDialog(parent)
{
QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8"));
createButton();
connect(OKButton, SIGNAL(clicked(bool)), this, SLOT(accept()));
setMinimumSize(320, 240);
}
/**/
void AddPoint::createButton()
{
XpointL = new QLabel("Point X:", this);
XpointL->setFixedSize(100, 30);
XpointL->move(10, 10);
XPoint = new QLineEdit(this);
XPoint->setFixedSize(180, 30);
XPoint->move(120, 10);
OKButton = new QPushButton("OK", this);
OKButton->setFixedSize(100, 30);
OKButton->move(200, 150);
}
After running the program i see in aplication output lap:
"The program has unexpectedly finished."
"C:\QT\build-xxx-Desktop_Qt_5_4_2_MSVC2013_64bit-Debug\debug\xx.exe crashed"
I note that i made some experiments with this code and i saw that i have problem with signal accpeted() at mainwindow.cpp. I don't know what can i do with this problem. I hope you will help me.
AddPointDialog is uninitialized pointer, it does not yet point to valid AddPoint in MainWindow's constructor. You cannot call connect on that. Its value will change later, when you do AddPointDialog = new AddPoint(this); and only then will you be able to call connect.
Simply, you should move your connect call to void MainWindow::PointClicked() after you've initialized your pointer. I'd also make AddPointDialog local to that function and store it on the stack (you don't use it anywhere else and you're leaking memory).
The code would be:
void MainWindow::PointClicked()
{
AddPoint AddPointDialog(this);
AddPointDialog.setModal(true);
connect(&AddPointDialog, SIGNAL(accepted()), this, SLOT(DialogAccepted()));
AddPointDialog.exec();
}

How to create object widget in other widgets in QT

In my application im having three widgets named as "Widget" , "one" and "two" . i tried to create the objects of the widget in main function as pass it as an argument to another widgets . it compiles successfully but application crashed before running , refer my code below and guide me,
//main.cpp
#include <QtGui/QApplication>
#include "widget.h"
#include "one.h"
#include "two.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget *w;
One *one;
Two *two;
w->GetObject(one,two);
one->GetObject(w,two);
two->GetObject(one,w);
w->show();
return a.exec();
}
//widget.cpp
#include "widget.h"
Widget::Widget(QWidget *parent) :QWidget(parent)
{
setupUi(this);
}
void Widget::GetObject(One *onee, Two *twoo)
{
one=onee;
two=twoo;
}
//widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include "ui_widget.h"
class One;
class Two;
class Widget : public QWidget, private Ui::Widget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
One *one;
Two *two;
void GetObject(One *onee, Two *twoo);
};
#endif // WIDGET_H
//one.cpp
#include "one.h"
One::One(QWidget *parent) :QWidget(parent)
{
setupUi(this);
}
void One::GetObject(Widget *widgett, Two *twoo)
{
widget = widgett;
two = twoo;
}
void One::on_pushButton_clicked()
{
widget->show();
}
//one.h
#ifndef ONE_H
#define ONE_H
#include "ui_one.h"
class Widget;
class Two;
class One : public QWidget, private Ui::One
{
Q_OBJECT
public:
explicit One(QWidget *parent = 0);
Widget *widget;
Two *two;
void GetObject(Widget *widgett, Two *twoo);
private slots:
void on_pushButton_clicked();
};
#endif // ONE_H