You are not logged in.

Dear visitor, welcome to QtForum.org. If this is your first visit here, please read the Help. It explains in detail how this page works. To use all features of this page, you should consider registering. Please use the registration form, to register here or read more information about the registration process. If you are already registered, please login here.

1

Tuesday, May 26th 2009, 11:50pm

Accessing ui widgets from another class

I don't claim to be a C++ expert and I'm pretty new to Qt, but for the life of me i can't seem to figure out how to access a line edit within another c++ source file.
Basically my main header file "arsenal.h" looks like this:

Source code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#ifndef ARSENAL_H
#define ARSENAL_H

#include <QtGui/QMainWindow>
#include <QModelIndex>

class QSqlTableModel;
class QString;


namespace Ui
{
	class Arsenal;
}

class Arsenal : public QMainWindow
{
	Q_OBJECT

public:
	Ui::Arsenal *ui;
	Arsenal(QWidget *parent = 0);
	~Arsenal();

private slots:
	void OpenDB();
	void SubAddClient();
	void SubDropClient();
	void SubAddProject();
	void SubDropProject();
	void PopProjView( const QModelIndex &index );
	void StartClock();
	void StopClock();
	void StoreUsername();


private:

	QSqlTableModel *model;
	QSqlTableModel *projmodel;
	QSqlTableModel *runmodel;
};

#endif // ARSENAL_H



I can access this no problem from my "arsenal.cpp" file, but since ui is declared as private I can't access it in any other cpp file. If I make Ui::Arsenal *ui public and I try to get lineEdit text from whatever.cpp:

Source code

1
Arsenal::ui->txtUserName->text()

I then get this error from the compiler:

Source code

1
C:/Documents and Settings/Derek/Desktop/arsenalDb/arsenalDb/Arsenal/arsenal.h:21: error: object missing in reference to `Arsenal::ui'


Like I said, I'm new to Qt, so there may be a simple solution in keeping "Ui::Arsenal *ui" private... I just don't know enough to figure out what to search for. Any help is greatly appreciated.

2

Thursday, May 28th 2009, 6:53am

Source code

1
Aresenal::Ui->...


If I remember correctly (I am doing C++ after years of doing managed code), you can only do this if the ui member variable is static. I believe you need to pass an instance of the Arsenal class, something like this:

Source code

1
2
3
4
void OtherObject::ProcessArsenalLineEdit(Arsenal * a)
{
a->ui->lineEdit->...
}

MasterBLB

Intermediate

  • "MasterBLB" is male

Posts: 188

Location: Poland/Wrocław

  • Send private message

3

Thursday, May 28th 2009, 7:03am

It's very simple,'cause this is an ordinary variable.So,after definition like yours,you can acess it like that:
1.create the Arsenal class instance,ex Arsenal a;
2.you get the acess to ui by using sentence a.ui then.But remember to make the ui a public variable,or about declaration of friendship between Arsenal and the class whitch will use the ui
3.that's all ;] ui doesn't need to be static,or passed as argument

But I'll give you a warning too-do not use the same name to the class and the designer form,this often causes problems
There are 10 kinds of people.Those who do understand the binary code,and those who do not ;)

4

Saturday, June 6th 2009, 12:32pm

Outstanding! Thank you gentlemen, works like a charm!

5

Saturday, June 6th 2009, 4:22pm

Guess I got a little too excited to soon. It compiles without complaint, but when I try to access my widget on the ui, it just crashes - every time.

I've kept "ui" public in my header file...
I create an instance in my cpp function:
Arsenal * a;

and access the widget like so: a->ui->lineEdit....

and it crashes with the old bomb message. I'm stumped again!!!

MasterBLB

Intermediate

  • "MasterBLB" is male

Posts: 188

Location: Poland/Wrocław

  • Send private message

6

Saturday, June 6th 2009, 6:45pm

if the form is defined as it's written:

Source code

1
Ui::Arsenal *ui;

then you try to acess an non-existing object,therefore the crashes.
Remove that star from definition,and it should be okay ;)
There are 10 kinds of people.Those who do understand the binary code,and those who do not ;)

7

Sunday, June 7th 2009, 12:24am

That is correct.
I changed:

Source code

1
2
public:
	Ui::Arsenal *ui;


to

Source code

1
2
public:
	Ui::Arsenal ui;


And the compiler now gives me the error: field 'ui' has incomplete type.

MasterBLB

Intermediate

  • "MasterBLB" is male

Posts: 188

Location: Poland/Wrocław

  • Send private message

8

Sunday, June 7th 2009, 11:02am

hmmmm...
Coud you give the form as an attachment to post?

Moreover,I don't see a line:

Source code

1
#include "ui_Arsenal.h"

at definition of your class
Remove that namespace Ui,it's done inside that ui_Arsenal.h
There are 10 kinds of people.Those who do understand the binary code,and those who do not ;)

9

Sunday, June 7th 2009, 1:08pm

Thank you so much for the help... I think I'm getting close to completing this project.

Here is my header file. I don't really understand what you're asking me to change. I'm really a perl / assembler guy, so I'm still kind of new to this style of programming...

Source code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#ifndef ARSENAL_H
#define ARSENAL_H

#include <QtGui/QMainWindow>
#include <QModelIndex>
#include <QSqlDatabase>
#include "ui_arsenal.h"

class QSqlTableModel;
class QString;
class QLabel;
class QPalette;
class QPushButton;
class QLineEdit;

namespace Ui
{
	class Arsenal;
}

class Arsenal : public QMainWindow
{
	Q_OBJECT

public:
	Arsenal(QWidget *parent = 0);
	~Arsenal();


public slots:
	void OpenDB();

private slots:
	void on_actionOpen_Report_triggered();
	void on_actionReconnect_to_Server_triggered();
	void on_actionPort_Number_triggered();
	void on_actionSet_Database_Password_triggered();
	void on_actionDatabase_Name_triggered();
	void on_actionSet_Database_Username_triggered();
	void on_actionSet_Server_Host_IP_Address_triggered();
	void on_action_Open_triggered();
	void on_actionGenerate_Report_triggered();
	void on_actionRemove_Project_triggered();
	void on_actionAdd_Project_triggered();
	void on_actionRemove_Client_triggered();
	void on_actionAdd_Client_triggered();
	//void OpenDB();
	void PopProjView( const QModelIndex &index );
	void StartClock();
	void StopClock();
	void StoreUsername();
	void UpdateRunModel();
	void UpdateViews();

public:
	Ui::Arsenal *ui;

private:
	//Ui::Arsenal *ui;
	QSqlTableModel *model;
	QSqlTableModel *projmodel;
	QSqlTableModel *runmodel;
	QLabel *dbstatusLabel;
	QPalette *pal;
};

#endif // ARSENAL_H


What do you think / what should I change here?
I changed ui back to *ui, because it would not compile.

Best regards,
Derek

10

Sunday, June 7th 2009, 2:19pm

Any chance I could do this with some kind of global namespace? I don't care if this one variable is set globally. I know that defeats the purpose of OOP, but I just want to get this thing running!
If so, could you provide an example of how this would be done? I'm trying to work through some examples, but they just give me a bunch of object errors during compile.

MasterBLB

Intermediate

  • "MasterBLB" is male

Posts: 188

Location: Poland/Wrocław

  • Send private message

11

Sunday, June 7th 2009, 4:20pm

namespace Ui
{
class Arsenal;
}

This seems to be wrong-remove it.

And tell me,do you set the ui content to the main window?I mean(if ui is set as varialbe) inside the constructor:

Source code

1
ui.setupUi(this);

If you examine the code of ui_Arsenal.h,you see a lot of pointers to widget you made inside Designer.But they start to exist only when you invoke the setupUi method-that is probably the reason your program crashes
There are 10 kinds of people.Those who do understand the binary code,and those who do not ;)

Junior

Professional

  • "Junior" is male

Posts: 1,623

Location: San Antonio, TX USA

Occupation: Senior Secure Systems Engineer

  • Send private message

12

Monday, June 8th 2009, 2:15pm

perlmonkey,

The namespace is defined for the form within the form.ui you created. To view it do:
uic form.ui
This will dump to stdout the ui_form.h code it is going to generate. Towards the bottom of other you will note the Ui namespace name it has defined.

There are several ways of referencing it within the header once the ui_form.h file is created. Noteably you do need to include it as mentioned from MasterBLB.
#include "ui_form.h"

Then as any other namespace you can decide how you want to work with it. If you want it private or public to your class.
(e.g.
class Arsenal : public QMainWindow, private Ui_FORM (replace Ui_FORM the namespace here)
class Arsenal : public QMainWindow, public Ui_FORM (replace Ui_FORM with namespace)

Because you are inheriting the namespace through the class define you will have scope of the namespace widgets/functions/etc...
Then you can just reference the widgets normally without stipulating or deferencing the Ui throughout your code.

ui->lineEdit->setPlainText( "text" ); // incorrect
lineEdit->setPlainText( "text" ); // correct
)

To access the form you will need to call the function from the ui_form.h: setupUi() from within the constructor of your class. Example provided from MasterBLB.

Hope this is helpful,

Junior