C++ accessing object, QT - c++

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;
}

Related

Downloading txt file with qtnetwork

I am trying to download a txt file from a url in QT but i can't seem to make it work.
I am following this guide https://wiki.qt.io/Download_Data_from_URL. I implemented the filedownloader class exactly like it's made in the guide, but when i try to use it like specified in the guide I cannot make it work. I created a slot to be called when the download is finished, but if i try to call the downloader inside like the guide it says it is an undeclared identifier.
Does anyone know how to correctly implement this code?
this is the .cpp of my code
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "mainwindow.h"
#include <QStringList>
#include <QCoreApplication>
#include <QFile>
#include <QFileInfo>
#include <QList>
#include <QtNetwork/QNetworkReply>
#include <QStringList>
#include <QTimer>
#include <QUrl>
#include <QtNetwork/QNetworkAccessManager>
#include <QtNetwork/QNetworkRequest>
#include <filedownloader.h>
#include <iostream>
#include <QObject>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
QUrl emiurl( "url of my file");
// call to the downloader class.In the guide it's made differently, but it doesn't work
FileDownloader emiload(emiurl,this);
//this connect links the end of the download with the textwriter slot
QObject::connect(&emiload, SIGNAL (downloaded()), this, SLOT (textwriter()));
}
>MainWindow::~MainWindow()
{
delete ui;
}
//slot needed to create the txt file from the downloaded one
void MainWindow::textwriter()
{
QByteArray emibyte;
emibyte=emiload->downloadedData(); //this line gives me error
QFile emifile("emi.txt");
emifile.open(QIODevice::WriteOnly);
std::cout << emibyte.size() << std::endl;
QDataStream out(&emifile);
out << emibyte;
std::cout << emifile.size() << std::endl;
}
Now here's the .h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include "filedownloader.h"
#include <QMainWindow>
#include <QtNetwork/QNetworkAccessManager>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private:
Ui::MainWindow *ui;
private slots:
void textwriter();
};
#endif // MAINWINDOW_H
To make the undeclared identifier go away and successfully compile, you need to add FileDownloader to the class' declaration. This way, it will be known throughout the class.
I chose to go with the approach that's usual in Qt, to declare a pointer to FileDownloader.
#pragma once // <--- this is supported by virtually any compiler today
#include <QMainWindow>
#include <QtNetwork/QNetworkAccessManager>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class FileDownloader; // <-- forward declaration is enough, but you can also #include "filedownloader.h"
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget* parent = nullptr);
~MainWindow();
private:
Ui::MainWindow* ui = nullptr;
FileDownloader* emiload = nullptr; // <--- the important line!
private slots:
void textwriter();
};
And then instantiate and call emiload in the constructor:
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
// create an instance of FileDownloader with "new".
emiload = new FileDownloader(QUrl("url of my file"), this);
// using member pointer connection available since Qt5
connect(emiload, &FileDownloader::downloaded, this, &MainWindow::textwriter);
}

Access widgets in QMainWindow from another class

Although it is a frequently asked question, and I've tried many ways including those from SO, like Trying to access widgets of MainWindow from another class, However I still cannot work out a solution, below is my code which reported error "Unknown type name 'CustomClass'" in mainwindow.h:
Thanks in advance for any help!
customclass.h
#ifndef CUSTOMCLASS_H
#define CUSTOMCLASS_H
#include "mainwindow.h"
#include "ui_mainwindow.h"
class MainWindow;
class CustomClass
{
public:
CustomClass(MainWindow *parent);
MainWindow * mainWindow;
void testFunc();
};
#endif // CUSTOMCLASS_H
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "customclass.h"
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
Ui::MainWindow *ui;
CustomClass *customClass = new CustomClass(this);
};
#endif // MAINWINDOW_H
customclass.cpp
#include "customclass.h"
CustomClass::CustomClass(MainWindow *parent)
{
this->mainWindow = parent;
}
void CustomClass::testFunc()
{
mainWindow->ui->label->setText("Hello World!");
}
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
customClass->testFunc();
}
MainWindow::~MainWindow()
{
delete ui;
}
main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
please read about Circular Dependencies in C++ .
you have problems because you create a loop, you included #include "customclass.h" in MainWindow class and also #include "mainwindow.h" in CustomClass .
it's better that you don't use MainWindow in other classes and add CustomClass objects in MainWindow. The idea is that MainWindow is your root window class and we create one object from it in main.cpp you can do what you ask but logically it's not good.
as we can see in QMainWindow Class document.
The QMainWindow class provides a main application window
A main window provides a framework for building an application's user
interface.
This is your base, you should add the feature you want inside this class not add it in other widgets.
It's the main class for other widgets. This is a clean way to code and if you look at big projects in GitHub you will see this.
move #include "mainwindow.h" and #include "ui_mainwindow.h" inside customclass.h into customclass.cpp before #include "customclass.h" and it works! Thank you!#drescherjm
The fixed code is shown below:
customclass.h
#ifndef CUSTOMCLASS_H
#define CUSTOMCLASS_H
class MainWindow;
class CustomClass
{
public:
CustomClass(MainWindow *parent);
~CustomClass();
MainWindow *mainWindow;
void testFunc();
};
#endif // CUSTOMCLASS_H
customclass.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"//Move these two lines from the header to here
#include "customclass.h"
CustomClass::CustomClass(MainWindow *parent)
{
this->mainWindow = parent;
}
CustomClass::~CustomClass()
{
}
void CustomClass::testFunc()
{
mainWindow->ui->label->setText("Hello World!");
}

Qt Change label text from another class

i'm trying to change the label text of Class A via Class B using Qt but i can't get it working, here's my codes:
Class A:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "loldata.h"
using namespace std;
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
LoLData *lold = new LoLData();
QObject::connect(ui->pushButton, SIGNAL(clicked()), this, SLOT(updateData()));
QObject::connect(lold, SIGNAL(updatePlayerID(QString)), ui->label, SLOT(setText(QString)));
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::updateData()
{
LoLData summoner;
summoner.getSummonerData("Snylerr");
}
Class A: (.h)
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QObject>
#include <string>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void updateData();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
Class B:
#include "loldata.h"
#include "mainwindow.h"
using namespace std;
int LoLData::getSummonerData(QString playerName)
{
emit updatePlayerID("playerName");
return 0;
}
Class B: (.h)
#ifndef DEF_LOLDATA
#define DEF_LOLDATA
#include <QApplication>
#include <QObject>
#include <string>
class LoLData : public QObject
{
Q_OBJECT
public:
int getSummonerData(QString playerName);
signals:
void updatePlayerID(QString playerName);
private:
};
#endif
You can see that i tried to use slots and signals but the text of the label is not changing, i saw a lot of examples on internet but i can't get them working
Thanks for your reply.
You are creating a new instance of LoLData here:
void MainWindow::updateData()
{
LoLData summoner;
summoner.getSummonerData("Snylerr");
}
This instance of LoLData named summoner is not connected to your label's setText slot.
LoLData *lold = new LoLData(); - this instance of LolData is connected to you label's setText slot.
What should yo do?
It depends on what you want to accomplish:
either connect your summoner instance to the label by inserting a QObject::connect(&summoner...) inside yourupdateData` method;
or you don't instantiate a new LolData variable and use lold inside your updateData function:
void MainWindow::updateData()
{
lold->getSummonerData("Snylerr");
}
Also in this case you have to put lold as a member variable.
In your MainWindow constructor, you connect your lold object to the setText slot.
But in updateData, you use an other object (summoner) which is not connect to anything. So when you use getSummonerData on summoner, the signal updatePlayerID is emitted nut they is no slot connected to it.

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.

initializing class A (with a reference member) within class B

i'm trying to make a simple currency converter and I have some problems with my class designed to make the calculations.
I want to create an object of this class in my MainWindow to use the total variable for displaying the result in a widget on my appi form.
Member functions aren't all here yet, but the problem I have is that i get a
'Calculator' : no appropriate default constructor available error in mainwindow.cpp
While I do know what that means, I don't know how to avoid (solve) the issue because i kind of need the reference on the map to get the echange rates needed.
.cpp
#include <QObject>
#include <QString>
#include <QDebug>
#include <ui_mainwindow.h>
class Calculator
{
public:
explicit Calculator(QMap<QString,double> &currency_map);
void multiply(double x, double y);
void getValues(QString strFrom, QString strTo);
private:
double total, firstCurr, secondCurr;
QMap<QString,double> &map;
};
.h
#include "calculator.h"
Calculator::Calculator(QMap<QString,double> &currency_map):map(currency_map)
{
total = 0;
firstCurr = 0;
secondCurr= 0;
}
void Calculator::getValues(QString strFrom, QString strTo)
{
QMapIterator<QString, double> i(map);
while(i.hasNext())
{
if(i.key() == strFrom)
firstCurr=i.value();
if(i.key() == strTo)
secondCurr = i.value();
}
}
void Calculator::multiply(double x, double y)
{
total = x * y;
}
and now im trying to create an object of that class in my MainWindow class:
#include <QMainWindow>
#include <ui_mainwindow.h>
#include "calculator.h"
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QMap<QString,double> &currency_map, QWidget *parent = 0);
~MainWindow();
private:
Ui::MainWindow *ui;
parser currency_parser;
Calculator calc; // error
};
MainWindow.h
MainWindow::MainWindow(QMap<QString, double> &currency_map, QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
ui->from_Combox->addItems(currency_parser.currency_list);
ui->to_Combox->addItems(currency_parser.currency_list);
}
the idea behind was that i have a Map in my main in which i save all my data needed and pass the map around to classes that use it.
i'll post my main even tho im not sure if it's needed
#include "downloader.h"
#include "mainwindow.h"
#include "parser.h"
#include "calculator.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QMap<QString,double> currency_map;
downloader d;
d.Do_download();
parser p;
p.read_line(currency_map);
MainWindow w(currency_map);
w.show();
return a.exec();
};
The error occurs, because you don't specify the appropriate constructor for class Calculator in the MainWindow constructors member initializer list (the compiler want's to use the default constructor then):
MainWindow::MainWindow(QMap<QString, double> &currency_map, QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
, calc(currency_map) // <<<<<<<<<<<<<<
{
// ...
}