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

Friday, April 27th 2012, 8:13pm

Creating QWidget from string

Hi all,

In my current design, I have a list of objects (Class1.cpp, Class2.cpp, Class3.cpp) where all of the objects are sub-classed from QWidget. I would like to be able to dynamically create the class from the string "Class1" or "Class2", etc. From google, the only things that I've seen are to create the classes directly using a switch statement. Since this is a generic core application class (used by a lot of other applications), I would need it to be a nicer solution than the brute force method.

I saw references to doing it with QMetaType, but it doesn't seem to work with the QWidget (or I may be implementing it wrong).

Any help is greatly appreciated.

Doug

2

Friday, April 27th 2012, 8:45pm

qmetaobject will work. show what you have so far...
If you have a problem, CUT and PASTE your code. Do not retype or simplify it. Give a COMPLETE and COMPILABLE example of your problem. Otherwise we are all guessing the problem from a fabrication where relevant details are often missing.

3

Monday, April 30th 2012, 12:37pm

The code that I have for my class (that I need dynamically created):
-----------------------------------------------

// Define statement to ensure that only this header
// file is included once
#ifndef PROCESSWORKAREAUI_H
#define PROCESSWORKAREAUI_H

// Include Files
#include
#include "ui_ProcessWorkAreaUI.h"

// Class Declaration
class ProcessWorkAreaUI : public QWidget
{
// Macros
Q_OBJECT

public:
// Constructors/Destructor
ProcessWorkAreaUI(QWidget *parent = 0);
~ProcessWorkAreaUI();

private:
// Variables
Ui::ProcessWorkAreaUIClass m_ui;
};

Q_DECLARE_METATYPE(ProcessWorkAreaUI)
--------------------------------------------

When I compile this, I get the error that: "error C2248: 'QWidget::QWidget' : cannot access private member declared in class 'QWidget'". I'm assuming that it refers to the m_ui member variable. However, I need this declaration since this QWidget is shown to the users.

Doug

#endif // PROCESSWORKAREAUI_H

4

Monday, April 30th 2012, 5:16pm

I'm assuming that it refers to the m_ui member variable
No, it isn't. m_ui isn't even in QWidget.

Show complete code and indicate what line gives compiler error. Didn't I already ask for your code?

Adding Q_INVOKABLE infront of your ctor will make it available in the qmetaobject
If you have a problem, CUT and PASTE your code. Do not retype or simplify it. Give a COMPLETE and COMPILABLE example of your problem. Otherwise we are all guessing the problem from a fabrication where relevant details are often missing.

5

Monday, April 30th 2012, 6:17pm

you could try creating a map

Source code

1
QMap<QString,FNcreate> widgetCreate;

where
- the key is a widget class name
- FNCreate is the type of a function creating a widget
then

Source code

1
2
3
4
if( FNCreate fn = widgetCreate["SomeClass"] )
{
    QWidget * widget = fn();
}

6

Tuesday, May 1st 2012, 1:02pm

First of all... thanks for the help, everybody! I really appreciate this:
@Amletto: Well, I provided the ".h" file. Here's the entire code:

AddImagesWorkAreaUI.cpp
-----------------
#include "AddImagesWorkAreaUI.h"

// Constructor
AddImagesWorkAreaUI::AddImagesWorkAreaUI(QWidget *parent)
:ProcessWorkAreaUI(parent)
{
m_ui.setupUi(this);
}

// Destructor
AddImagesWorkAreaUI::~AddImagesWorkAreaUI()
{
}
-----------------

AddImagesWorkAreaUI.h
-----------------
#ifndef ADDIMAGESWORKAREAUI_H

#define ADDIMAGESWORKAREAUI_H
#include "ProcessWorkAreaUI.h"
#include "ui_AddImagesWorkAreaUI.h"

class AddImagesWorkAreaUI : public ProcessWorkAreaUI
{
Q_OBJECT

public:
Q_INVOKABLE AddImagesWorkAreaUI(QWidget *parent = 0);
virtual ~AddImagesWorkAreaUI();

private:
Ui::AddImagesWorkAreaUIClass m_ui;

}; <--------------------------- [Error: QWidget::QWidget cannot access private member declared in class QWidget']

Q_DECLARE_METATYPE(ProcessWorkAreaUI)

#endif // ADDIMAGESWORKAREAUI_H
--------------

The error is at the ";" of the .h file

@Nicolas: What is the FNCreate? I can't seem to find any reference to it? Do you have an example cpp/h that would show how to do this?

Dougie

7

Tuesday, May 1st 2012, 7:10pm

code tags please! Your code is virtually unreadable.

FNCreate is something you have to do yourself.

isn't there anything else to the error message? I think the error should be invoked from somewhere else. It looks to me like it should come from a copy constructor or assignment.


and there still isnt COMPLETE code here. Do you know why I ask for complete and compilable code? because it makes it 100x easier for everyone else if they can just copy/paste and compile for themselves.

It saves us having to go through this merry dance every single effin time of asking for code that is missing, what line number is? what is the error message? No, you missed a bit, ... and then at the end of it, we have to be the intelligent compiler and fill in blanks.

Just give the code next time... in code tags.
If you have a problem, CUT and PASTE your code. Do not retype or simplify it. Give a COMPLETE and COMPILABLE example of your problem. Otherwise we are all guessing the problem from a fabrication where relevant details are often missing.

8

Tuesday, May 1st 2012, 7:25pm

an example of what I was thinking

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
// map that can be initialized at declaration
template<typename K, typename V> struct MyMap : 
    public                              QMap<K,V>
{
    MyMap<K,V> & add( K k, V v ) { (*this)[k] = v; return( *this ); }
};

// type of a funtion taking no parameter and returning a pointer to a QWidget
typedef QWidget * (* FCreateWidget) ();

struct Widget0 : public QWidget
{
    Widget0() : QWidget() { setWindowTitle( "Widget0" ); }
    // thist method is of type FCreateWidget
    static QWidget * create() { return( new Widget0 ); } 
};

struct Widget1 : public QWidget
{
    Widget1() : QWidget() { setWindowTitle( "Widget1" ); }
    // thist method is of type FCreateWidget
    static QWidget * create() { return( new Widget1 ); }
};

struct Widget2 : public QWidget
{
    Widget2() : QWidget() { setWindowTitle( "Widget2" ); }
    // thist method is of type FCreateWidget
    static QWidget * create() { return( new Widget2 ); }
};

// a map associating a class name to a creation function
static MyMap<QString,FCreateWidget> createMap = MyMap<QString,FCreateWidget>()
   .add( "Widget0", Widget0::create )
   .add( "Widget1", Widget1::create )
   .add( "Widget2", Widget2::create );

int main( int ac, char * * av )
{
    QApplication   app( ac, av );

    for( int i = 0; i < 10; i++ )
    {
        QString classe = QString( "Widget%1" ).arg( i );
        if( FCreateWidget fn = createMap[classe] )
        {
            fn()->show();
        }
    }

    return( app.exec() );
}

This post has been edited 1 times, last edit by "Nicolas SOUCHON" (May 2nd 2012, 9:17am)


9

Tuesday, May 1st 2012, 8:09pm

Okay... sorry about not using the code tags (didn't realize that there a special tag for formatting them). The error is:

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
1>------ Build started: Project: SpineStudio, Configuration: Debug x64 ------
1>Compiling...
1>moc_AddImagesWorkAreaUI.cpp
1>ProcessStepList.cpp
1>ProcessStep.cpp
1>AddImagesWorkAreaUI.cpp
1>c:\projects\qt_products\spinestudio\viewer\source\ProcessWorkAreaUI.h(24) : error C2248: 'QWidget::QWidget' : cannot access private member declared in class 'QWidget'
1>        c:\development\languages\qt\qt64\include\qtgui\../../src/gui/kernel/qwidget.h(806) : see declaration of 'QWidget::QWidget'
1>        c:\development\languages\qt\qt64\include\qtgui\../../src/gui/kernel/qwidget.h(147) : see declaration of 'QWidget'
1>        This diagnostic occurred in the compiler generated function 'ProcessWorkAreaUI::ProcessWorkAreaUI(const ProcessWorkAreaUI &)'
1>c:\projects\qt_products\spinestudio\viewer\source\ProcessWorkAreaUI.h(24) : error C2248: 'QWidget::QWidget' : cannot access private member declared in class 'QWidget'
1>        c:\development\languages\qt\qt64\include\qtgui\../../src/gui/kernel/qwidget.h(806) : see declaration of 'QWidget::QWidget'
1>        c:\development\languages\qt\qt64\include\qtgui\../../src/gui/kernel/qwidget.h(147) : see declaration of 'QWidget'
1>        This diagnostic occurred in the compiler generated function 'ProcessWorkAreaUI::ProcessWorkAreaUI(const ProcessWorkAreaUI &)'
1>c:\projects\qt_products\spinestudio\viewer\source\ProcessWorkAreaUI.h(24) : error C2248: 'QWidget::QWidget' : cannot access private member declared in class 'QWidget'
1>        c:\development\languages\qt\qt64\include\qtgui\../../src/gui/kernel/qwidget.h(806) : see declaration of 'QWidget::QWidget'
1>        c:\development\languages\qt\qt64\include\qtgui\../../src/gui/kernel/qwidget.h(147) : see declaration of 'QWidget'
1>        This diagnostic occurred in the compiler generated function 'ProcessWorkAreaUI::ProcessWorkAreaUI(const ProcessWorkAreaUI &)'
1>c:\projects\qt_products\spinestudio\viewer\source\ProcessWorkAreaUI.h(24) : error C2248: 'QWidget::QWidget' : cannot access private member declared in class 'QWidget'
1>        c:\development\languages\qt\qt64\include\qtgui\../../src/gui/kernel/qwidget.h(806) : see declaration of 'QWidget::QWidget'
1>        c:\development\languages\qt\qt64\include\qtgui\../../src/gui/kernel/qwidget.h(147) : see declaration of 'QWidget'
1>        This diagnostic occurred in the compiler generated function 'ProcessWorkAreaUI::ProcessWorkAreaUI(const ProcessWorkAreaUI &)'
1>Build log was saved at "file://c:\Projects\QT_Products\SpineStudio\viewer\debug64\BuildLog.htm"
1>SpineStudio - 4 error(s), 0 warning(s)
========== Build: 0 succeeded, 1 failed, 9 up-to-date, 0 skipped ==========


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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
// File: ProcessWorkAreaUI.cpp
// Purpose: Basic Ancestor class for all work area widgets
// Application Include Files
#include "ProcessWorkAreaUI.h"

/***************************************************************************/
/* Constructor.                                                             */
/***************************************************************************/
ProcessWorkAreaUI::ProcessWorkAreaUI(QWidget *parent)
: QWidget(parent)
{
	// Create the dialog controls
	m_ui.setupUi(this);
}

/***************************************************************************/
/* Destructor                                                           */
/***************************************************************************/
ProcessWorkAreaUI::~ProcessWorkAreaUI()
{

}

// File: ProcessWorkAreaUI.h
// Define statement to ensure that only this header
// file is included once
#ifndef PROCESSWORKAREAUI_H
#define PROCESSWORKAREAUI_H

// Include Files
#include <QWidget>
#include "ui_ProcessWorkAreaUI.h"

// Class Declaration
class ProcessWorkAreaUI : public QWidget
{
	     // Macros      
             Q_OBJECT
 public:	    
          // Constructors/Destructor	
           ProcessWorkAreaUI(QWidget *parent = 0);	
           ~ProcessWorkAreaUI();

private:	
           // Variables	
           Ui::ProcessWorkAreaUIClass m_ui;
};

#endif // PROCESSWORKAREAUI_H

// File: AddImagesWorkAreaUI.cpp
// Purpose: General work area for adding images. Inherited from ProcessWorkAreaUI
// Application Include Files
#include "AddImagesWorkAreaUI.h"

/***************************************************************************/
/* Constructor.                                                            */
/***************************************************************************/
AddImagesWorkAreaUI::AddImagesWorkAreaUI(QWidget *parent)
:ProcessWorkAreaUI(parent)
{
	m_ui.setupUi(this);
}

/***************************************************************************/
/* Destructor	                                                           */
/***************************************************************************/
AddImagesWorkAreaUI::~AddImagesWorkAreaUI()
{
}

// File: AddImagesWorkAreaUI.h
// Define statement to ensure that only this header
// file is included once
#ifndef ADDIMAGESWORKAREAUI_H
#define ADDIMAGESWORKAREAUI_H

// Include Files
#include "ProcessWorkAreaUI.h"
#include "ui_AddImagesWorkAreaUI.h"

// Class Declaration
class AddImagesWorkAreaUI : public ProcessWorkAreaUI
{
	// Macros
	Q_OBJECT

public:
	// Constructors/Destructor
	Q_INVOKABLE AddImagesWorkAreaUI(QWidget *parent = 0);
	~AddImagesWorkAreaUI();

private:
	// Variables
	Ui::AddImagesWorkAreaUIClass m_ui;
};

Q_DECLARE_METATYPE(ProcessWorkAreaUI)

#endif // ADDIMAGESWORKAREAUI_H

10

Tuesday, May 1st 2012, 8:31pm

just like I said...

Source code

1
ProcessWorkAreaUI::ProcessWorkAreaUI(const ProcessWorkAreaUI &)

you cant have copy ctors with QObjects/QWidgets.

remove them.


If you have more ctors like this,
ProcessWorkAreaUI(QWidget *parent = 0);
make sure you add explicit keyword in front of them:

Source code

1
explicit ProcessWorkAreaUI(QWidget *parent = 0);
If you have a problem, CUT and PASTE your code. Do not retype or simplify it. Give a COMPLETE and COMPILABLE example of your problem. Otherwise we are all guessing the problem from a fabrication where relevant details are often missing.

11

Wednesday, May 2nd 2012, 2:12pm

Okay, I'm sorry to be deft about this. I don't have the copy constructor. That copy constructor code that you show is part of the error message.

12

Wednesday, May 2nd 2012, 5:41pm

I know you don't. The error message says it is compiler generated. That means somewhere in your code you are copying that class, or the compiler is making the ctor for you anyway (I think this wont happen).

Did you add explicit in front of ALL of your ctors that have 'QWidget* parent' in them?

Another thing you can do is merely add

Source code

1
2
private:
ProcessWorkAreaUI(const ProcessWorkAreaUI &);


into your ProcessWorkAreaUI class def. You should not write the implementation. If you get a linker error, then you know you have some code that copies that class, which as I said, isn't allowed.
If you have a problem, CUT and PASTE your code. Do not retype or simplify it. Give a COMPLETE and COMPILABLE example of your problem. Otherwise we are all guessing the problem from a fabrication where relevant details are often missing.

Similar threads