Qt/C++ - Accessing Mainwindow UI from a Different Class

Access Qt UI of another Class from the MainWindow Class

Qt foresees its signals and slots approach for such purposes.

The QPushButton of your class offers a signal clicked which you connect to a custom (self-written) slot of your dialog. The dialog's slot then should read the contents of the QLineEdit and publish these on the dialogs own (custom) signal, which is connected to a (custom) slot of your main window, which then can process the value originally contained in the line edit.

Details will resemble pretty much the example of Qt's signals and slots documentation, so I won't be more explicit about.

Trying to access widgets of MainWindow from another class

you are trying to find the widget label using the ui pointer, so it can be found only including the ui_mainwindow in the initializer...

your approach is kind of weird but you can do:

#include <QWidget>
#include "ui_mainwindow.h"
class Init
{
public:
Init(Ui::MainWindow *ui);
};

#include "Init.h"

Init::Init(Ui::MainWindow *ui)
{
ui->pushButton1s->setText("11111");
}

and pass the ui in the constructor:

MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent),  ui(new Ui::MainWindow)
{
ui->setupUi(this);
Init a(ui);

Qt GUI Easiest way to access MainWindow from another class

No way in general, because some applications may have several (toplevel) QMainWindow-s (and their list could change with time). So for that case you'll better pass the pointer to it (the particular QMainWindow you want to deal with) explicitly....

A possible way might be to have your specific subclass of QApplication (which is a singleton class, see QCoreApplication::instance to get its sole instance) and in your application subclass put, as fields, the explicit windows you want to deal with (maybe you even want to add some new signal or slot to your application class).

However, you could use QGuiApplication::topLevelWindows() or QGuiApplication::allWindows() to get the list of all such windows. Notice that a QWindowList is just a QList<QWindow *>. So see QList for how to traverse or iterate on that list.

Once you have found which QMainWindow you want, adding a QLabel into it is usual practice (but again, signals & slots could be helpful).

BTW, each (displayed) widget has its window, see QWidget::window()


About your code:

Your Main_Window is really poorly named (and the name is so confusing that I cannot use that). It is a list not a window. So code first:

QMainWindow* mainWindow = nullptr;
{
QList<QWindow*> topwinlist = QGuiApplication::topLevelWindows();
int nbtopwin = topwinlist.size();
for (int ix=0; ix<nbtopwin; ix++) {
QWindow*curwin = topwinlist.at(ix);
if (curwin->objectName() == "mainWindow")
mainWindow = dynamic_cast<QMainWindow*>(curwin);
}
}

I did not test the above code and I am not sure it is correct or even can compile. But why don't you just have a global pointer to your main window:

 MainWindow*mymainwinp = nullptr;

and initialize it appropriately in your main body:

int main(int argc, char *argv[]) {
srand(time(NULL));
QApplication a(argc, argv);
MainWindow w;
mymainwinp = &w;
w.show();
int r = a.exec();
mymainwinp = nullptr;
return r;
}

then use mymainwinp elsewhere (e.g. in your Test)? If you want more elegant code, define your own subclass of QApplication and have mymainwinp be a field in it.

Qt5 access the ui from another class

You need to #include "ui_mainwindow.h" in your datafunctions.cpp file. It's a header which is automatically generated by Qt Designer and it defines the Ui::MainWindow class.

Access Qt ui from another class

Sailordi, the error is in the way you're including the header files.
I did some modifications that should fix it. However I'd like to tell you that what you're doing is not a good programming practice.

MainWindow.h

#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:
Ui::MainWindow *ui;
};

#endif // MAINWINDOW_H

MainWindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "message_function.h"

message_function MeFu;

MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
MeFu.Print(ui);
}

MainWindow::~MainWindow()
{
delete ui;
}

message_function.h

#ifndef MESSAGE_FUNCTION_H
#define MESSAGE_FUNCTION_H

#include "mainwindow.h"

class message_function
{
public:
void Print(Ui::MainWindow *ui);
};

#endif // MESSAGE_FUNCTION_H

message_function.cpp

#include "message_function.h"
#include "ui_mainwindow.h"

void message_function::Print(Ui::MainWindow* ui)
{
ui->label->setText("This is a test");
}

C++ /Qt Proper way to access ui from another class in qt //Edited

The root of your problem is that you seem to be misunderstanding the concept of pointers. Specifically, calling new is not the only way to obtain a pointer - a pointer is just a variable that holds the address of some object (or function). The new operator returns a pointer to a dynamically-allocated object, but there are other ways too, at least three of which are relevant to you:

1) Have someone else give you a pointer, for example as a function parameter;

2) Use & to take the address of an object.

3) Use this to get a pointer to the object you are currently working with.

Now that we have that out of the way, take a look at your code. MainWindow has two slots:

class MainWindow : public QMainWindow {
Q_OBJECT
...
public slots:
void on_Button_clicked();
void displayMessage();

Slots are member functions - they are called on an object.

When you create an object of type MainWindow, the on_Button_clicked slot of your MainWindow object is automatically connected to the clicked signal of Button (via the meta-object compiler, a Qt-specific thing, because of the particular naming convention that you used).

What happens to the other one? Here's your code:

void GLWidget::mouseReleaseEvent(QMouseEvent *e){  
MainWindow *mwd;
mwd= new MainWindow;
QObject::connect(this, SIGNAL(valueCh()), mwd ,SLOT(displayMessage()) );
emit valueCh();
delete mwd;
}

Rather than connecting to the slot of the original MainWindow object, you are creating a new object, calling its function, and promptly destroying it. So, while the slot does get called, it doesn't get called on the object that is actually your gui.

This is happening because you figured you needed a pointer to a MainWindow object, and used new to get one. The problem is, that pointer didn't point to the object you actually care about (i.e. your actual gui).

One (inelegant) solution is to not create a new MainWindow; instead, pass the address of the original MainWindow to the widget, and use that address (pointer) in the connect statement.

The much better solution is to skip all that stuff and use signals and slots the way they were intended, so that individual widgets don't have to know anything about the objects they are being connected to.

Change your MainWindow constructor to the following:

MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
connect(ui->glWidget, SIGNAL(mouseReleaseEvent()),this,SLOT(displayMessage()));

}

and get rid of everything but the emit statement inside GLWidget::displayMessage.

Access MainWindow class members from another class

libinsert will not be a child of MainWindow. QDialog-based windows are always top-level windows, regardless of what you pass as their parent when you construct them.

If there will only ever exist a single instance (per process) of MainWindow at any given time, you can give MainWindow a static function which returns a pointer to the window:

class MainWindow : public QMainWindow
{
public:
MainWindow()
{
theWindow = this;
}

virtual ~MainWindow()
{
theWindow = nullptr;
}

static get()
{
return theWindow;
}

static MainWindow *theWindow;
}

MainWindow *MainWindow::theWindow = nullptr;

Your dialogs can then access the main window's members thusly:

MainWindow::get()->someMemberFunction();

A more robust approach is to have libinsert store a pointer to the main window when it is created:

class MainWindow;

class libinsert : public QDialog
{
public:
libinsert(MainWindow *mw)
: mainWindow(mw)
{ ... }

MainWindow *getMainWindow()
{
return mainWindow;
}

MainWindow *mainWindow;
}

When MainWindow creates the dialog, it passes a pointer to itself to the constructor:

void MainWindow::createDialog()
{
libinsert *dialog = new libinsert(this):
}

This approach will work even if there are multiple instances of MainWindow active at the same time.



Related Topics



Leave a reply



Submit