[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]


  • Moderators

    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.


  • Moderators

    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!



  • Thanks, I'll give it a try.



  • Hi mlong,

    I think you meant:

    MainWindow.cpp:
    @
    MainWindow::someMethod() {
    userEntry->userdata(&info); // Pass the address of info.
    // or
    userEntry->userdata(info); // using reference
    }
    @

    as userEntry is a pointer to the UserEntry class...



  • 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_OBJECT

    public:
    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.



  • That seems to have come from copying and pasting. The definitions are okay in my files.



  • [quote author="CapnMikey" date="1315495836"]That seems to have come from copying and pasting. The definitions are okay in my files.[/quote]
    Then please update your previous post to reflect the actual state of your code.



  • Line 15 in Information.h should be line 25 in MainWindow.h. Sorry about the mixup.



  • [quote author="CapnMikey" date="1315496093"]Line 15 in Information.h should be line 25 in MainWindow.h. Sorry about the mixup.[/quote]
    Please just use the Edit button next to your post to modify it and fix the mixup.



  • Okay, the code above has been modified.

    Thanks for pointing out the edit button.



  • Your struct is named information, but the definition in mainwindow.h is Information. C++ is case sensitive...



  • I corrected the case error as well (see post above). I still get the same error message.



  • 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]



  • I added line 13 to the MainWindow.cpp above, but I still get the same error message. Is this what you are referring to?



  • Either, change line 20 in MainWindow.h to
    @
    Information info;
    @
    and remove line 13 from MainWindow.cpp, or

    change 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++.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.