Using GUI member variables in a subclass

Do you have a question about makefiles, a compiler or IDE you are using and need to know how to set it up for wxWidgets or why it doesn't compile but other IDE's do ? Post your questions here.
RuudH
In need of some credit
In need of some credit
Posts: 9
Joined: Thu Jun 04, 2020 6:35 am

Using GUI member variables in a subclass

Post by RuudH » Fri Jun 19, 2020 8:56 am

I created a Code::Blocks MinGW project on Windows 10 Pro to see if I could use a mmember variable in a sub class.
This is the first time I created such a subclass (I only created ones without gui access needs)

The gui is created with wxFormBuilder.
The basic project consists of 3 element:
GUIFrame; which has all member variables of the gui (2 sliders, 1 button and 2 staticTexts),
ClassTestApp; which only has the OnInit function,
ClassTestMain; which has a function m_btn1_OnButtonClick.

m_btn1_OnButtonClick gets the value of the 1st slider and copies the value to the 1st staticText.

Constructor of ClassTestFrame and OnButtobClick function:

Code: Select all

ClassTestFrame::ClassTestFrame(wxFrame *frame) : GUIFrame(frame)
{}
void ClassTestFrame::m_btn1_OnButtonClick( wxCommandEvent& event )
{
    Test1 t1(this);  // inserted after creating the subclass
    t1.VarTest();    // inserted after creating the subclass

    int x{m_slider1->GetValue()};
    wxString s{};
    s << "Slider 1 is set to: " << x;
    m_staticText1->SetLabelText(s);

}
Sofar so good all works fine.

Then I used wxFormBuilder to add a subclass called Test1 (Tools - Generate Inherited Class).
In Test1 I have a function call VarTest wich gets the value of the 2nd slider and copies the value to the 2nd staticText.

Constructor in Test1 and function VarTest:

Code: Select all

Test1::Test1( wxWindow* parent ) : GUIFrame( parent )
{}
void Test1::VarTest()
{
    int x{m_slider2->GetValue()};
    wxString s{};
    s << "Slider 2 is set to: " << x;
    m_staticText2->SetLabelText(s);
    std::cout << s << std::endl;  // Console feedback on slidervalue
}
All compiles without errors,
but when running it, the slider 2 value stays on the default value (it does not change after moving)
and the static text remains unchanged.

Searching through forums I found 1 suggestion:

Code: Select all

this->GetParent()->m_staticText1->SetLabelText("test");
But this creates an error: 'class wxWindow' has no member named 'm_staticcText2.

I hope someone can help me
RuudH

User avatar
doublemax
Moderator
Moderator
Posts: 14976
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Using GUI member variables in a subclass

Post by doublemax » Fri Jun 19, 2020 2:43 pm

Code: Select all

this->GetParent()->m_staticText1->SetLabelText("test");
This is definitely wrong and can never work. As the error message states, GetParent() just returns a wxWindow which doesn't know about the member variables of your custom class.

The rest of your code doesn't make much sense though.

Code: Select all

    Test1 t1(this);  // inserted after creating the subclass
    t1.VarTest();    // inserted after creating the subclass
a) you're creating a wxFrame on the stack, which is not allowed

b) you're creating a completely new instance. The member variables in the Test1 instance are not the same as in the ClassTestFrame instance.

In principle, what you did should work. Just your test code is bad.
Use the source, Luke!

ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 4245
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: Using GUI member variables in a subclass

Post by ONEEYEMAN » Fri Jun 19, 2020 3:38 pm

Hi,
What you should do is to look at the minimal sample and see how things done with wxWidgets.

Thank you.

RuudH
In need of some credit
In need of some credit
Posts: 9
Joined: Thu Jun 04, 2020 6:35 am

Re: Using GUI member variables in a subclass

Post by RuudH » Sat Jun 20, 2020 6:05 am

Hi,
Thank you for your replies.
I also tried:

Code: Select all

Test1 *t1;
t1->VarTest();
This also compiles but the application crashes when accessing a gui member variable.
I learned both methods in a course (albeit a very old one using Visual Studio 6).
wxWidgets work differently I realize now (after pausing my hobby for more than a decade).

I dissected the minimal example.
I may be stupid, but I do not see it. I apologize for that
It roughly works the way I have it without the Test inherited class

I attached my small Code::Blocks test project so you can see the whole thing.
Your help is much appreciate to open my eyes and learn how to use wxWidgets (which I really like).
Attachments
ClassTest.rar
(15.29 KiB) Downloaded 9 times

ONEEYEMAN
Part Of The Furniture
Part Of The Furniture
Posts: 4245
Joined: Sat Apr 16, 2005 7:22 am
Location: USA, Ukraine

Re: Using GUI member variables in a subclass

Post by ONEEYEMAN » Sat Jun 20, 2020 6:31 am

Hi,
You just a have a dangling pointer here - one that is not being initialized.
And so of course it will crash.

However as doublemax suggested you should look at the minimal sample and see how to create a window with wxWidgets properly (with a pointer) so that it will be properly destroyed.

This is all C++ - whether you work under MSVC 6 or 19. It doesn't really matter.

Thank you.

User avatar
doublemax
Moderator
Moderator
Posts: 14976
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Using GUI member variables in a subclass

Post by doublemax » Sat Jun 20, 2020 7:28 am

Code: Select all

void ClassTestFrame::m_btn1_OnButtonClick( wxCommandEvent& event )
{
    Test1 *t1 = new Test1(this);
    t1->Show();
    t1->VarTest();

    int x{m_slider1->GetValue()};
    wxString s{};
    s << "Slider 1 is set to: " << x;
    m_staticText1->SetLabelText(s);

}
Use the source, Luke!

RuudH
In need of some credit
In need of some credit
Posts: 9
Joined: Thu Jun 04, 2020 6:35 am

Re: Using GUI member variables in a subclass

Post by RuudH » Sat Jun 20, 2020 8:52 am

Thank you doublemax.

I tried your advice, but it shows a second window with the default slider2 value.
Moving the slider does not change the value (25).

Please see attached screenshot.
Attachments
ClassTest2.jpg
ClassTest2.jpg (41.72 KiB) Viewed 362 times

User avatar
doublemax
Moderator
Moderator
Posts: 14976
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Using GUI member variables in a subclass

Post by doublemax » Sat Jun 20, 2020 9:28 am

I tried your advice, but it shows a second window with the default slider2 value.
Yes, that's exactly what this code does. What did you expect or want to happen?
Moving the slider does not change the value (25).
That's not surprising as there is no event handler in your code that catches changing the slider value.
Use the source, Luke!

RuudH
In need of some credit
In need of some credit
Posts: 9
Joined: Thu Jun 04, 2020 6:35 am

Re: Using GUI member variables in a subclass

Post by RuudH » Sat Jun 20, 2020 9:56 am

Thank you for being patient with me.

What I like to achieve is the following:
Create one gui window class that can be used in multiple subclasses.

For example a mediaplayer.
The main class handles the drag and drop of mp3 files into a listbox, and lots more.
A second class handles all the functions for playing music.
(which includes moving a slider that follows elapsed time in the gui window class, selecting the next mp3 to play from the listbox, etc.)
A third class retrieves tags like album name, track title, coverart, etc. which are displayed in the gui window class.

This means that 3 classes need access to the member variables in one single gui window class.

I hope this can be done somehow.
This is what my small test is about.
The minimal sample did not help me much. If the solution is in there I have become blind for it :-(.

User avatar
doublemax
Moderator
Moderator
Posts: 14976
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Using GUI member variables in a subclass

Post by doublemax » Sat Jun 20, 2020 10:54 am

Thanks, i think i understand now. But inheritance/subclassing is not the right way to solve this. Instead have the new classes take a pointer to the gui class and communicate between the classes using public methods. Don't make member variables public, don't modify them from other classes directly.

Here's a dummy example for an mp3 player class:

Code: Select all

class MP3Player
{
public:
  MP3Player( GuiClass *parent ) {
    // save pointer to guiclass for later use
    m_parent = parent;
  };
 
  void PlayFile( const wxString &path) {...}
  
  void OnProgress() {
    m_parent->SetProgress(...)
  }
  
protected:
  GuiClass *m_parent;
}
Use the source, Luke!

RuudH
In need of some credit
In need of some credit
Posts: 9
Joined: Thu Jun 04, 2020 6:35 am

Re: Using GUI member variables in a subclass

Post by RuudH » Sat Jun 20, 2020 11:30 am

Thank you very much.

By now I have stared myself blind :-(.
That's what happens when I try something new on the wrong path.
I think I begin to understand what you are saying (my old retired brain needs some processing time :-) ).

I am afraid to ask, but how does that reflect to my small project?
What does it take to make it work?
I think I need a working example to have my AHA moment (or OMG how could I be this stupid).

User avatar
doublemax
Moderator
Moderator
Posts: 14976
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Using GUI member variables in a subclass

Post by doublemax » Sat Jun 20, 2020 1:02 pm

I'm not sure how to help you from here. Maybe you should stop planing ahead too far and just start coding. The first project will always be a mess. But afterwards you'll know what to do differently next time.
Use the source, Luke!

RuudH
In need of some credit
In need of some credit
Posts: 9
Joined: Thu Jun 04, 2020 6:35 am

Re: Using GUI member variables in a subclass

Post by RuudH » Sat Jun 20, 2020 2:05 pm

I started coding in the 1990's.
Mostly Free Pascal with Lazarus.
Stopped, and now I have all the time in the world, picked it up again in February 2019.
Created several apps; some in C# some in MFC, most in C++.
Always had all code in the same class (for some reason I did not think any further).

The last one (the media player) was finished 3 weeks ago.
As Code::Blocks creates projects : Guiframe, App, Main.
All code resides in the main class (including audio and tag retrieval library calls).
Last week I discovered that I need to replace the audio part, and found out that this was more work than anticipated.

That is why I want to make the new version modular with 3 separate files/classes for audio tags and a variety of other things such as DnD.
Before messing up the original code, I decided to create a small test project to find the best way forward.
It got me stuck. Searched the web for answers. Nothing useful, nothing worked the way I need it.
Always referring to something that did not fulfill my vision of modular programming.

There must be examples somewhere from which I can learn modular programming.
Have not found them though.
Anyway,
Thank you very much (or as we say in Malaysia: Terima kasih banyak-banyak)

User avatar
doublemax
Moderator
Moderator
Posts: 14976
Joined: Fri Apr 21, 2006 8:03 pm
Location: $FCE2

Re: Using GUI member variables in a subclass

Post by doublemax » Sat Jun 20, 2020 3:53 pm

Last week I discovered that I need to replace the audio part, and found out that this was more work than anticipated.
Then this should be a good starting point. Try to separate the audio player functionality from everything else, especially the GUI. Put everything in a separate class (no subclassing). Then define which public interface you need - both on the GUI and on the audio side - in order for these parts to cooperate.
Use the source, Luke!

RuudH
In need of some credit
In need of some credit
Posts: 9
Joined: Thu Jun 04, 2020 6:35 am

Re: Using GUI member variables in a subclass

Post by RuudH » Sun Jun 21, 2020 3:09 am

Separating the new audio module will not be a problem, because I will have to start from scratch with that.
Removing the current one will need careful commenting out first, before final deletion.

What I still cannot do (and what my small project was all about) is sharing the current gui in multiple modules.
As soon as (if ever) I have found a way to do that, I will start work on the new audio module.

Post Reply