Qt acess ui of different class - c++

I am trying to access the ui elements of different class but getting error message. I've tried to do this for many hours but still failing, I feel that I am missing something simple.
I am trying to access an element "label" which is in form.h
mainwindow:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "form.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
Form * elemForm = new Form(this);
elemForm->ui; // works
//elemForm->ui->label; // does not work
}
MainWindow::~MainWindow()
{
delete ui;
}
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 = 0);
~Form();
Ui::Form *ui;
private:
};
#endif // FORM_H
form.cpp
#include "form.h"
#include "ui_form.h"
Form::Form(QWidget *parent) :
QWidget(parent),
ui(new Ui::Form)
{
ui->setupUi(this);
ui->label; //works fine here
}
Problem is in mainwindow file. I know this is inappropriate code, I'm just interested what I'm doing wrong. I am struggling to find whats wrong, any ideas?

In addition to form.h, you should also include ui_form.h in your MainWindow.h.
That's because the form elements are all defined in Ui::Form which is accessible by including :
#include "ui_form.h"

Please, try to think on what are you doing, and how to do things better.
Don't feel think that method explained by Nejat is controversial to OOP? If you are trying to use OOP, learn how to do it and use it.
To get deeper understanding on what am I talking about, please, read this short story about encapsulation.
Back to your example. Here is clean, simple and easy way to do what you want:
Your mainwindow.h:
#include "mainwindow.h"
#include "ui_mainwindow.h"
// Include only header of your Form, not ui_form.h!
#include "form.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
Form* elemForm = new Form(this);
// Use public method of your Form object!
elemForm->changeUI();
}
Your form.h:
#include <QWidget>
namespace Ui {
class Form;
}
class Form : public QWidget
{
Q_OBJECT
public:
explicit Form(QWidget *parent = 0);
~Form();
void changeUI(); // here you can do all what you want with your UI
private:
Ui::Form *ui;
};
in form.cpp you'll have realization:
void Form::changeUI()
{
ui->... // do all what you want with UI
}

Related

Qt can't compile

I am new with QT and c++. So I do this tutorial Tutorial
I copied everything, but qt can't compile this.
//imageviewer.cpp
#include "imageviewer.h"
#include "ui_imageviewer.h"
ImageViewer::ImageViewer(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::ImageViewer)
{
ui->setupUi(this);
QImage image("C:/TEST/GoldenGate.png");
ui->imageLabel->setPixmap(QPixmap::fromImage(image));
}
ImageViewer::~ImageViewer()
{
delete ui;
}
//imageviewer.h
#ifndef IMAGEVIEWER_H
#define IMAGEVIEWER_H
#include <QMainWindow>
#include <QLabel>
#include <QScrollArea>
namespace Ui {
class ImageViewer;
}
class ImageViewer : public QMainWindow
{
Q_OBJECT
public:
explicit ImageViewer(QWidget *parent = 0);
~ImageViewer();
private:
QLabel *imageLabel;
QScrollArea *scrollArea;
Ui::ImageViewer *ui;
};
#endif // IMAGEVIEWER_H
And got this:
'class Ui::ImageViewer' has no member named 'imageLabel'
I can't understand why it doesnt't see this variable.
Your Ui::ImageViewer is not complete .. it does not have 'imageLabel' added. Open the form in design mode and add QLabel, name it 'imageLabel' and try again.
Otherwise, follow tutorial to the end, it adds the QLabel 'imageLabel' dynamically in imageview.cpp.
// imageview.cpp
#include "imageviewer.h"
#include "ui_imageviewer.h"
ImageViewer::ImageViewer(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::ImageViewer)
{
ui->setupUi(this);
imageLabel = new QLabel;
imageLabel->setBackgroundRole(QPalette::Base);
imageLabel->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored);
imageLabel->setScaledContents(true);
scrollArea = new QScrollArea;
scrollArea->setBackgroundRole(QPalette::Dark);
scrollArea->setWidget(imageLabel);
setCentralWidget(scrollArea);
setWindowTitle(tr("Image Viewer"));
resize(500, 400);
}

QT signal-slot not received

I am trying to connect a signal from a second QMainWindow to the mainwindow. It doesn't say anything about a problem connection when the program is launched, but It doesn't work. I am not very familiar with C++ and Qt so maybe is something simple.
My code consists on a Mainwindow used as a SCADA with Start, stop, On, off buttons. In the second qmainwindow I created a terminal where you can type, start,stop... There, I would like to emit a signal to my MainWindow which is in charge of controlling the multiple threads and windows. The problem is that I cannot connect to my slot. I present here a simple overview of this two pieces of code.
Terminal. h
#ifndef TERMINAL__H
#define TERMINAL__H
#include <QMainWindow>
#include <QTextEdit>
#include <QLineEdit>
#include <QObject>
namespace Ui {
class Terminal_;
}
class Terminal_ : public QMainWindow
{
Q_OBJECT
public:
explicit Terminal_(QWidget *parent = 0);
~Terminal_();
signals:
void turnonPLC_terminal();
public slots:
void newline();
private:
Ui::Terminal_ *ui;
QTextEdit* mTerminal;
QLineEdit* mInput;
};
#endif // TERMINAL__H
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "terminal_.h"
#include "terminal_help.h"
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
Terminal_ *terminal;
public slots:
void turnon_terminal();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
Mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "terminal_.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
terminal = new Terminal_(this);
connect(terminal, SIGNAL(turnonPLC_terminal()), this, SLOT(turnon_terminal()));
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::turnon_terminal(){
turnonPLC=1;
}
terminal_.cpp
#include "terminal_.h"
#include "ui_terminal_.h"
#include <QDockWidget>
#include <QWidget>
#include <QLineEdit>
QString on=("on");
Terminal_::Terminal_(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::Terminal_)
{
ui->setupUi(this);
mTerminal = new QTextEdit();
setCentralWidget(mTerminal);
mInput = new QLineEdit();
QDockWidget* qdw = new QDockWidget;
qdw->setWidget(mInput);
addDockWidget(Qt::BottomDockWidgetArea, qdw);
connect (mInput, SIGNAL(returnPressed()),
this, SLOT(newline()));
}
Terminal_::~Terminal_()
{
delete ui;
}
void Terminal_::newline(){
QString command = mInput->text();
if (command==on){
emit turnonPLC_terminal();
}
}
Thanks
The signal-slots part in the code works perfectly. (compiled and tested with some small modifications)
After entering "on" (not On as written in question)
Terminal_::newline() slot called, turnonPLC_terminal() is fired and finally
void MainWindow::turnon_terminal() is called.
However, there are some small details the header file is called terminal_.h, not Terminal.h turnonPLC is not defined. terminal is created by not displayed (no show-call).
I guess, there are simply some many small logic errors. Try to use debugger or trace the chain of expected calls with qDebug.

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")
{
...
}

How to connect a signal to a slot

I let Qt-Creator to generate me a basic window app using Qt. I added there a button and try to connect it to a slot. It compiles fine but the app crashes and returns 3, please help me, I don't know what to do.
#include "form1.h"
#include "ui_form1.h"
#include <iostream>
Form1::Form1(QWidget *parent) : QMainWindow(parent), ui(new Ui::Form1)
{
connect(ui->buttonLoad,&QPushButton::clicked,this,&Form1::ButtonLoadClick);
ui->setupUi(this);
}
Form1::~Form1()
{
delete ui;
}
void Form1::ButtonLoadClick(){
using namespace std;
cout << "click!" << endl;
}
In the header I only added one public slot.
#ifndef FORM1_H
#define FORM1_H
#include <QMainWindow>
namespace Ui {
class Form1;
}
class Form1 : public QMainWindow
{
Q_OBJECT
public:
explicit Form1(QWidget *parent = 0);
~Form1();
public slots: //here
void ButtonLoadClick(); //here
private:
Ui::Form1 *ui;
};
#endif // FORM1_H
Try:
Form1::Form1(QWidget *parent) : QMainWindow(parent), ui(new Ui::Form1)
{
ui->setupUi(this);
connect(ui->buttonLoad,&QPushButton::clicked,this,&Form1::ButtonLoadClick);
}
setupUi creates all visual components, including push button.

Qt Passing variables between unrelated objects

I am currently learning Qt and I seem to have run into a problem.
In my practice project I have 2 classes: MainWindow and Dialog.
MainWindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "dialog.h"
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
private slots:
void on_pushButtonDialog_clicked();
private:
Ui::MainWindow *ui;
Dialog *dialogInstance;
};
#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);
dialogInstance = new Dialog(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_pushButtonDialog_clicked()
{
dialogInstance->show();
}
Dialog.h
#ifndef DIALOG_H
#define DIALOG_H
#include <QDialog>
namespace Ui {
class Dialog;
}
class Dialog : public QDialog
{
Q_OBJECT
public:
explicit Dialog(QWidget *parent = 0);
~Dialog();
private:
Ui::Dialog *ui;
};
#endif // DIALOG_H
Dialog.cpp
#include "dialog.h"
#include "ui_dialog.h"
Dialog::Dialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog)
{
ui->setupUi(this);
}
Dialog::~Dialog()
{
delete ui;
}
My goal is to input a value using the Dialog window, then have the value of that input shown on the MainWindow, I know how to pass variables around within the class using widgets, but I am not sure how to transfer variables between unrelated objects.
Any input would be of great help.
Try this:
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
connect(ui->pushButtonDialog, SIGNAL(clicked()), this, SLOT(on_pushButtonDialog_clicked()));
dialogInstance = new Dialog(this);
}
// ...