[Moved] Document/View application
-
I am working on an application where I need to pass a large structure or structure array between classes.
The application contains three classes: MainWindow, UserEntry and Calculations
The structure has two parts: user data and calculated results.
What I would like to do is:
1) use the MainWindow to create, open, save, etc. the structure,
2) use the UserDataEntry class to allow the user to input data to the structure, and
3) use the Calculations class to parse the user data, perform calculations and store the calculated results in the structure.I need to be able to pass the structure (document) easily between the classes (views). Since the application is entirely self contained (no threading) making the structure global should work although I have been unable to get globals to work in Qt.
Instead of using a global structure I have been trying to get the following code to work for passing the structure between MainWindow and UserEntry:
MainWindow.h
#include "userentry.h"
public:
struct information
{
...
}info;MainWindow.cpp
...
userdata(&info);
...UserEntry.h
...
void userdata(struct information *info);
...UserEntry.cpp
void UserEntry::userdata(struct information *i)
{
...
}This gives an error message:
no matching function for call to 'UserEntry::userdata(MainWindow::information*)'
candidates are 'void UserEntry::userdata(information*)'I may have a simple syntax error, but I can't find it or any reference to what it could be. I would appreciate any observations on the syntax and references to public applications (such as examples) that use this approach.
Thanks.
[Edit: Moved to C++ Gurus; mlong]
-
Why not define Information in its own header file, rather than defining it within MainWindow.h? MainWindow can still own the working copy of the structure, but it may make for a cleaner implementation. You can just include "information.h" wherever it might be needed.
Also, in C++ you don't need to use the struct keyword when referring to the item in parameter lists, etc.. The struct name is sufficient. I.e., void UserEntry::userdata(Information *info) { }
-
Thanks for the quick reply.
Creating "information.h" seems like a good solution, but how can I make it work? How would MainWindow own the working copy and pass it to the other classes?
In Qt I kept getting compile errors when I didn't include the struct keyword in places where it seemed redundant.
-
Information.h:
@
struct Information {
// foo
};
@UserEntry.h:
@
#include "Information.h"
...
void userdata(Information *info) {...}; // Takes a pointer to info
// or
void userdata(Information &info) {...}; // Takes a reference to info
@MainWindow.h:
@
#include "Information.h"
...
private:
Information info;
UserEntry *userEntry;
@MainWindow.cpp:
@
MainWindow::someMethod() {
userEntry->userdata(&info); // Pass the address of info.
// or
userEntry->userdata(info); // using reference
}
@Edit: Corrected code. Thanks Gerolf!
-
Note that you might want to use forward declares in headers instead of includes. That means:
@
//MainWindow.h
struct Information;//...
private:
Information* m_information;
@and then only in the MainWindow.cpp do the #include of Information.h.
It makes compilation faster.
-
No luck - below is the MainWindow and Information code. I left out the UserData code to see if this would work before making it any more complex. This generates a compile error code:
request for member 'a' in 'info', which is of non-class type 'Information*'
Is this caused by a syntax error that I am missing?
MainWindow.h
@
#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>
#include "Information.h"namespace Ui {
class MainWindow;
}class MainWindow : public QMainWindow
{
Q_OBJECTpublic:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();private:
struct information *info;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); info = new information; info.a = "A"; info.b = "B"; info.c = "C";
}
MainWindow::~MainWindow()
{
delete ui;
}
@Information.h
@
#ifndef INFORMATION_H
#define INFORMATION_H#include <QtGui>
struct information
{
QString a;
QString b;
QString c;
};#endif // INFORMATION_H
@
Added @ tags around code sections. Please do that yourself next time; Andre
-
There seems to be some weird mismatch of #ifdefs and #endif's in your code. Perhaps you should fix these first?
Oh, and in your MainWindow, you have a pointer to an Information instance, while you do not seem to be creating an instance and trying to assign to it as if it is a normal member variable.
-
Did you also note the remark I posted above?
[quote author="Andre" date="1315495737"]Oh, and in your MainWindow, you have a pointer to an Information instance, while you do not seem to be creating an instance and trying to assign to it as if it is a normal member variable. [/quote]
-
Either, change line 20 in MainWindow.h to
@
Information info;
@
and remove line 13 from MainWindow.cpp, orchange line 20 in MainWindow.h to
@
Information* info;
@
and change lines 15-17 in MainWindow.cpp into:
@
info->a = "A";
info->b = "B";
info->c = "C";
@
and insert this line as line 24:
@
delete info;
@In either case, get yourself a good book on C++ to get yourself a solid introduction into the language you are working with. Qt does not shield you from having to learn C++.
-
Andre (and everyone else)-
Thanks for your help. The first option compiled correctly. Having seen something that works I hope I can figure it out from here.
Your last suggestion is appropriate. However, I have a large stack of books on C++ programming. The problem is the definition of the word "good". I learned chemical thermodynamics by using a large stack of textbooks. None of them were particulary good. But, where one authors explanation failed another author provided a more thorough explanation. I was able to piece it together that way. I haven't found that approach to work well for understanding C++.