How can I use common variable in multiple cpp file in Qt..? - c++

#include "main.h"
#include "ui_main.h"
Main::Main(QWidget *parent):
QMainWindow(parent),
ui(new Ui::Main)
{
ui->setupUi(this);
}
Main::~Main()
{
delete ui;
}
I have this header file main for Qt in which part should I create global variable

You can make use of extern variables. declare and define those variables
in any .h or .cpp file and you can use them in other files using extern
keyword and that variable name.
e.g. in my main.cpp I have Qstring A = "xyz";
suppose I have mainwindow.h and mainwindow.cpp
in mainwindow.h
extern Qstring A;
you will get the value of A in mainwindow.

If you really want to do that then you need to implement a Singleton class.
And after that you can use it like this:
class Common final
{
public:
Common& instance() // In the cpp.
{
static Common common;
return common;
}
static int value() // In the cpp.
{
return 11;
}
static std::string text() // In the cpp.
{
return "desired text";
}
private:
Common() // In the cpp.
{
}
};
Or just add some variables in a separate header file, but with OO I think it's better inside a class (or at least inside a namespace).

To use the variable of file in another file...
1.in the header file make a variable publically...
2.include that header file in another .cpp file...
3.to use the variable of that file make an object of the file and by using member operator...
//Main header file...
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "a.h"
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
int i=10;
~MainWindow();
private slots:
void on_pushButton_clicked();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
//in cpp file og
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_pushButton_clicked()
{
a obj;
obj.setModal(true);
obj.exec();
}
//the cpp file in which you want to use the variable...
//here make an object of the header file an use member operator...
#include "a.h"
#include "ui_a.h"
#include "mainwindow.h"
a::a(QWidget *parent) :
QDialog(parent),
ui(new Ui::a)
{
ui->setupUi(this);
}
a::~a()
{
delete ui;
}
void a::on_pushButton_clicked()
{
MainWindow obj;
qDebug()<<obj.i;
}

Related

How to update QWindow in qt c++, text doesn't show

I'm writing QT deskop app and I have a small issue.
I want to open new tab with text that I put from a file.
I have two class one in mainwindow.h and second in form.h
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
public slots:
void on_open_file_clicked();
void on_search_keyword_clicked();
void on_search_tag_clicked();
void on_tabWidget_tabCloseRequested(int index);
void show_tab(QString keywords);
QString return_text();
public:
Ui::MainWindow *ui;
private slots:
void on_actionOpen_file_triggered();
void on_actionShow_text_file_triggered();
QVector<QString>find_logs_keywords(QString keywords);
private:
QString text = "example text";
};
#endif // MAINWINDOW_H
form.h
#ifndef FORM_H
#define FORM_H
#include <QWidget>
namespace Ui {
class Form;
}
class Form : public QWidget
{
Q_OBJECT
public:
explicit Form(QWidget *parent = nullptr);
~Form();
public slots:
void on_pushButton_2_clicked();
void text_to_plain(QString& text);
private:
Ui::Form *ui;
};
#endif // FORM_H
mainwindow.cpp
#include <QFileDialog>
#include <QFile>
#include <QTextStream>
#include <QMessageBox>
#include <QDir>
#include <QVector>
#include <QStringList>
#include <iostream>
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "search_keyword.h"
#include "search_tag.h"
#include "form.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_open_file_clicked()
{
QString filter = "log file (*log) ;; Tex File (*.txt)";
QString file_name = QFileDialog::getOpenFileName(this, "Open a file", QDir::homePath(), filter);
QMessageBox::information(this,"..",file_name);
QFile file(file_name);
if (!file.open(QFile::ReadOnly | QFile::Text)) QMessageBox::warning(this,"title","file not open");
else
{
QTextStream in(&file);
text = in.readAll();
ui->plainTextEdit->setPlainText(text);
ui->lineEdit->setPlaceholderText(file_name);
}
file.close();
}
void MainWindow::on_actionShow_text_file_triggered()
{
show_tab("all logs");
Form Fr;
Fr.text_to_plain(text);
}
void MainWindow::show_tab(QString keywords)
{
ui->tabWidget->addTab(new Form(), QString("%1").arg(keywords));
ui->tabWidget->setCurrentIndex(ui->tabWidget->count()-1);
}
form.cpp
#include "form.h"
#include "ui_form.h"
Form::Form(QWidget *parent) :
QWidget(parent),
ui(new Ui::Form)
{
ui->setupUi(this);
}
Form::~Form()
{
delete ui;
}
void Form::text_to_plain(QString& text)
{
ui->plainTextEdit->setPlainText(text);
}
My problem is after call method void MainWindow::on_actionShow_text_file_triggered() plain text in QWidget in Form is still empty i tried: this->update, this->repaint, Form::update(); Form::repaint(), QWidget::repaint(); QWidget::update();. Everything fail.
the problem is that your Form exists only in this function scope.
void MainWindow::on_actionShow_text_file_triggered()
{
show_tab("all logs");
Form Fr;
Fr.text_to_plain(text);
}
Here -> Form Fr; the Form is created: constructor(explicit Form(QWidget *parent = nullptr);) of the class Form is called
And at this place -> } your Form is deleted: destructor(~Form();) of class Form is called.
This happens because you create your Form instance on the function stack. So Fr is local object and exist only in the scope of the function on_actionShow_text_file_triggered() after the function is executed/finished all local variables are freed/destructed.
if your Fr object should exist not just in this function you need to create it on the heap instead of stack.
P.S.: for case study read about stack vs heap for example hear: What and where are the stack and heap?
Your on_actionShow_text_file_triggered function should then look like this:
void MainWindow::on_actionShow_text_file_triggered()
{
show_tab("all logs");
Form * Fr = new Form(this); //if you set parent object your Form will be automatically deleted/destructed then MainWindow is deleted/destructed
Fr->text_to_plain(text);
Fr->show(); // you should call show() function of QWidget class and subclasses to get your widget visible
}
This Form * Fr = new Form(this); will create new form pointer every time. Would not it be better to create one global pointer to the form, call the functions and delete it later?

Using object directly from another class c++

Hi i have 3 classes that i want to use. but i dont want to create object of one class more than once. I directly want to use the object (in third class) of one class declared and initialized in second class.
To understand the problem please focus on NetworkConnection members and class defined in example below.
Class Mainwindow header
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "secondscreen.h"
#include "networkconnection.h"
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
NetworkConnection *NetworkConnectionObject;
private slots:
void on_pushButton_clicked();
private:
Ui::MainWindow *ui;
SecondScreen* SecondScreenObject;
};
#endif // MAINWINDOW_H
Class Main Window cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "QMessageBox"
#include "networkconnection.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
NetworkConnectionObject = new NetworkConnection();
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_pushButton_clicked()
{
int Error = NetworkConnectionObject->Connect(Username,Password);
///////////////
// This Works
//////////////
NetworkConnectionObject->LogInToken = "";
}
Class NetworkConnection Header
#ifndef NETWORKCONNECTION_H
#define NETWORKCONNECTION_H
#include <QString>
class NetworkConnection
{
public:
NetworkConnection();
int Connect(QString Username, QString Passwd);
QString LogInToken;
};
#endif // NETWORKCONNECTION_H
Now i want to use Networkclassobject directly in SeconScreenclass so that i can access LogInToken Member of MainWindowInstance.
#include "secondscreen.h"
#include "ui_secondscreen.h"
#include "mainwindow.cpp"
SecondScreen::SecondScreen(QWidget *parent) :
QDialog(parent),
ui(new Ui::SecondScreen)
{
ui->setupUi(this);
///////////////
// This doesnot work
//////////////
MainWindow::NetworkConnectionObject->LogInToken = "";
}
SecondScreen::~SecondScreen()
{
delete ui;
}
However, when i try this compiler says
Invalid use of non-static data member "MainWindow::NetworkConnectionObject" Problem is i dont want to declare it static. Is there any way to do it.
Without seeing secondscreen.h I can't say for sure but MainWindow::NetworkConnectionObject" doesn't reference a specific instance of MainWindow class, you must reference a specific instance to modify.
If in your SecondScreen header you have something like
class SecondScreen {
// . . .
MainWindow window;
// . . .
}
then in your constructor for SecondScreen you must use the initialized instance of MainWindow, i.e.
SecondScreen::SecondScreen(QWidget* parent) : QDialog(parent) {
window.NetworkConnectionObject->LogInToken = "";
}

Creating a global object in QT GUI

I am trying to create an object called x from a class "Fan" inside the QT GUI mainwindow file, where I want it to be global. I want QT's button slot functions to be able to perform operations on the object. However, a compiler error "error: C4430: missing type specifier - int assumed" always occurs. Here is the header file:
#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 slots:
void on_btOn_clicked();
void on_btOff_clicked();
private:
Ui::MainWindow *ui;
Fan x; // This doesn't work
Fan * x; // This doesn't either
int x; // This does work
};
#endif // MAINWINDOW_H
And here is the cpp file:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "fan.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_btOn_clicked()
{
ui->lblState->setText("Fan is on");
}
void MainWindow::on_btOff_clicked()
{
x.turnOff(); // This does not work of course
x->turnOff(); // Or this
ui->lblState->setText("Fan is off");
}
I already told the cpp file to include the Fan class from the fan.h file. If I create the object within the window constructor, it initializes fine but is not global. Also, there is no circular inclusion of header files. Fan class does not include mainwindow.
Perhaps I don't know how to search for it, but I've already done some research into it to no avail. Any help is appreciated.
Edit:
Here is the fan.cpp file
#include "fan.h"
Fan::Fan(){
speed = 0;
isOn = false;
}
void Fan::setSpeed(int s){
speed = s;
}
int Fan::getSpeed(){
return speed;
}
void Fan::turnOn(){
isOn = true;
speed = 1;
}
void Fan::turnOff(){
isOn = false;
speed = 0;
}
bool Fan::getState(){
return isOn;
}
And the fan.h file:
#ifndef FAN_H
#define FAN_H
class Fan
{
private:
int speed;
bool isOn;
public:
Fan();
void setSpeed(int);
void turnOn();
void turnOff();
int getSpeed();
bool getState();
};
#endif // FAN_H
You forget to include or declare the class Fan in your Header File. If you use
Fan * x;
You could use
class Fan;
as a forward declaration at the beginning of your Header File. The Compiler only need to know that there is a class called Fan but inside the Header you only use a pointer. Butt don't forget to #include the real file in your CPP file.
If you use
Fan x;
you have to #include the Fan.h in your Header-File

How to use a class inside another class?

I'm developing a Qt application and I'm really new to C++. What I'm trying to do, is create a class as a variable and then use its contents from another class.
My structure and what I'm trying to do, indicated by --> and <--:
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include "settings.h"
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow {
Q_OBJECT
public:
-->BHSettings settings(qApp->applicationDirPath() + "/settings.ini");--<
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) {
ui->setupUi(this);
}
MainWindow::~MainWindow() {
delete ui;
}
void MainWindow::doSomething() {
-->settings.loadSettings();<--
}
settings.h
#ifndef BHSETTINGS_H
#define BHSETTINGS_H
#include <QSettings>
class BHSettings : public QSettings {
public:
QString theme;
BHSettings(QString settingsFilePath);
void loadSettings();
void saveSettings();
void saveSettings();
};
#endif // BHSETTINGS_H
settings.cpp
#include "settings.h"
BHSettings::BHSettings(QString settingsFilePath) : QSettings(settingsFilePath, QSettings::IniFormat) {
loadSettings();
saveSettings();
}
void BHSettings::loadSettings() {
theme = getTheme();
}
void BHSettings::saveSettings() {
setValue("General/Theme", theme);
}
QString BHSettings::getTheme() {
return value("General/Theme", "default").toString();
}
I'm completely lost as how to do this. Some guidance as how to define another class to use its methods would be great.
You had a great start but since your BHSettings class has a non-default constructor, in order to have it as a member variable you should initialize it into your constructor's initialization list
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow),
settings(qApp->applicationDirPath() + "/settings.ini") <--
{
ui->setupUi(this);
}
you can't initialize it in the class declaration as an inline-declaration or something like you were doing.
Also notice that this will cause your settings object to be initialized (i.e. BHSettings's object constructed) each time you instantiate the MainWindow class
Declare the member in the class definition without the initialization code.
BHSettings settings;
Add the initialization code in the constructor of the class.
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent), ui(new Ui::MainWindow),
settings(qApp->applicationDirPath() + "/settings.ini")
{
ui->setupUi(this);
}
You can use:
void MainWindow::doSomething() {
settings.loadSettings();
}
if you don't need the settings before that function. You may also call it in the constructor if that makes sense.
In your MainWindow class, define the variable:
public:
BHSettings settings;
In the constructor initialise this memeber:
MainWindow::MainWindow(QWidget *parent) : ... , settings(qApp->applicationDirPath() + "/settings.ini")
{
...
}

Qt phonon media object error

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <Phonon/MediaSource>
#include <QUrl>
#include <Phonon/MediaObject>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_pushButton_clicked()
{
QUrl url("http://www.example.com/music.ogg");
Phonon::MediaObject *wow =
Phonon::createPlayer(Phonon::NoCategory,
Phonon::MediaSource(url));
wow->play();
}
This code won't play the file, and I'm getting this error:
:: error: collect2: ld returned 1 exit status
Can anyone help me get the file to play when I click the button?
Thanks.
I guess that there are one or more functions declared in the header file but their bodies haven't been built yet.
for example:
//headerfile
class MyClass
{
public: MyClass();
private: void function1();
void function2();
};
//source file
MyClass::MyClass(){}
void MyClass::function1(){ /*do something*/ }
//here function2 is missing.
So, please check that all the functions in the whole project have their bodies.
For a basic phonon media player,
#ifndef MYVIDEOPLAYER_H
#define MYVIDEOPLAYER_H
#include <QWidget>
#include <QPushButton>
#include <Phonon/VideoPlayer>
#include <QVBoxLayout>
class MyVideoPlayer : public QWidget
{
Q_OBJECT
public:
explicit MyVideoPlayer(QWidget *parent = 0);
private:
Phonon::VideoPlayer *videoPlayer;
QPushButton *btnButton;
QVBoxLayout layout;
private slots:
void onPlay();
};
#endif // MYVIDEOPLAYER_H
#include "myvideoplayer.h"
MyVideoPlayer::MyVideoPlayer(QWidget *parent) :
QWidget(parent)
{
videoPlayer=new Phonon::VideoPlayer(Phonon::VideoCategory,this);
btnButton=new QPushButton("Play",this);
layout.addWidget(btnButton);
layout.addWidget(videoPlayer);
setLayout(&layout);
connect(btnButton,SIGNAL(clicked()),this,SLOT(onPlay()));
}
void MyVideoPlayer::onPlay()
{
videoPlayer->load(Phonon::MediaSource("movie.mp4"));
videoPlayer->play();
}
As templatetypedef commented, it sounds like a linker error. Ensure that you have added all of the necessary libraries to the .pro file. For example, you need to link against Phonon, so your .pro file must contain
QT += phonon