Re: [gtkmm] beginner´s question



"Andreas B. Thun" <abt gmx de> writes:

> Thx for your help...
>
>  > What are "guiRef" and "m_TreeBrowerBox"?
>
> The class ConstraintGui represents my main window.
> The main window should hold a notebook with a table
> ConstraintGui::m_TableBox and a tree browser, the
> ConstraintGui::m_TreeBrowserBox.
>
> - A Tree Browser Box is created by the constructor
>    of class ConstraintTypesBrowser.
> - A Table Box is created by the constructor of class
>    ConstraintTable.
>
> I must find a way to assign the created boxes to
> ConstraintGui::m_TableBox and ConstraintGui::m_TreeBrowserBox.
> ConstraintTypesBrowser and ConstraintTable are friend classes
> to ConstraintGui.
>
> The point is, I want to create every widget of my main window
> in a separate class. ConstraintGui::showGui puts every widget
> together.
>
> guiRef is a reference to ConstraintGui (my main window).
> I need a reference to this class because I want to assign
> the created boxes to the class members of ConstraintGui::m_TableBox
> and ConstraintGui::m_TreeBrowserBox.

I didn't have a lot of time to look at your code (and it wasn't
complete/compilable--send me a .tar.bz2 of the source privately if you
like; if it's Free Software, I'll be happy to have a hack on it, once
you've tried my suggestions).

Some comments follow.  Please bear in mind that I'm not an "expert";
these are just observations.

> main.cpp:
> int main(int argc, char **argv)
> {
>     // Init GUI
>     Gtk::Main kit(argc, argv);
>
>     // Create GUI
>     ConstraintGui cGui;           // main window = notebook with table + tree browser
>     ConstraintTable cTable(cGui); // table
>     ConstraintTypesBrowser cTypesBrowser(cGui); // tree browser

This design seems "backwards", if ConstraintGui /contains/ a
ConstraintTable and a ConstraintTypesBrowser, you should do this the
other way round (see below).

>     cGui.showGui(); // put all into a box and show it
>
>     // Shows the window and returns when it is closed.
>     Gtk::Main::run(cGui);
>
>     return 0;
> }

Why not consider doing this:

ConstraintTable cTable;
ConstraintTypesBrowser cTypesBrowser;

then:

ConstraintGui cGui;
cGui.set_constraint_table(cTable);
cGui.set_constraint_types_browser(cTypesBrowser);

or

ConstraintGui cGui(cTable, cTypesBrowser);

i.e. you have getter/setter functions to get/set them, or provide them
to the constructor.  Alternatively, have cGui contain them as member
data:

class ConstraintGui : public Gtk::Window
{
private:
  ConstraintTable m_Table;
  ConstraintTypesBrowser m_TypesBrowser;
public:
  ConstraintGui():
    m_Table(),
    m_TypesBrowser()
    {
      // Construct interface here and pack
      // these data members into the interface.
    }
}

> ConstraintGui.cpp:
> void ConstraintGui::showGui()
> {

This UI construction should really be in the ctor (or a private method
called by the ctor).  Since your class /is a/ widget, it should fully
construct itself and be ready to use.

When I have multiple constructors, I usually put the UI construction
into a private method called "construct"; Gtkmm calls it "construct_"
(Gtk::Dialog).

> }
>
>
> ConstraintGui.h:
>
>     //## Constraint Gui = Main Window
>     class ConstraintGui : public Gtk::Window {
>
>     public:
>       ConstraintGui();
>
>       virtual ~ConstraintGui();
>
>       ConstraintGui& operator=(const ConstraintGui& right);

Do you /really/ need a copy ctor for a widget?  I can't say I've ever
needed to do this: most methods take references or pass back
references/pointers rather than copying.

> 	void showGui();

Why not make this private and call at the end of the ctor?

> 	friend class ConstraintTypesBrowser;
> 	friend class ConstraintTable;

If you correct your "backwards" class usage, these won't need intimate
knowledge of this class.  IMHO they are not necessary, and if you
alter the design, they can be safely removed.

>     private:
> 	Gtk::VBox m_TreeBrowserBox;
> 	Gtk::VBox m_TableBox;
>
>     protected:
> 	// Signal handlers:
> 	virtual void on_button_quit();
>
>
>     }; // class
>
>
> ConstraintTypesBrowser.cpp:
>
> // Creates the TreeBrowser Box I want to assign to ConstraintGui::m_TreeBrowserBox
> ConstraintTypesBrowser::ConstraintTypesBrowser(
>    const ConstraintGui &guiRef,
>    :
>    m_Frame("ConstraintTypes:")
> {

[...]

>    // ??????
>    // ?????? How can I do this properly???
>    guiRef.m_TreeBrowserBox.pack_start(m_Frame);

Do this:
* Derive ConstraintTypesBrower from e.g. Gtk::Bin (a simple container).
* Construct just the browser (without the Frame) in the constructor.
* ConstraintGui contains this as a protected/private data member, and
  simply packs it into the appropriate container (e.g. the frame)
  within its constructor.

> ConstraintTable.cpp:
>
> // Creates the table box I want to assign to ConstraintGui::m_TableBox
> ConstraintTable::ConstraintTable(const ConstraintGui& guiRef)
> {
>    cout << "START ConstraintTable::ConstraintTable()" << endl;
>
>    // Create a Table and put it inside a ScrolledWindow
>    // Gtk::ScrolledWindow *scrolledWin = Gtk::manage(new Gtk::ScrolledWindow());
>    Gtk::Table          *table       = Gtk::manage(new Gtk::Table (10, 10, FALSE));
>
>    Gtk::VBox*VBox = Gtk::manage(new Gtk::VBox(false, 2));
>    VBox->pack_start(*table);
>
>    // ?????? How can I do this properly???
>    guiRef.m_TableBox = *VBox;

I'd do this as for the other class:
* Derive ConstraintTable from Gtk::Table.
* Construct the UI it contains in the constructor.
* ConstraintGui contains this as a protected/private data member, and
  simply packs it into the appropriate container within its
  constructor.

Basically, you are making your classes into standalone, reusable,
widgets which you can intantiate and pack into you interface wherever
you like, just like a Gtk::Button or any standard widget.  The widgets
contained by another widget don't need intimate knowledge of their
parent, which you should bear in mind in your design.


When you have got the hang of this, you will probably be interested in
looking at Glade/libglademm to ease interface construction.  You can
also load your own derived widgets on demand, too.


HTH,
Roger

-- 
Roger Leigh

                Printing on GNU/Linux?  http://gimp-print.sourceforge.net/
                GPG Public Key: 0x25BFB848.  Please sign and encrypt your mail.



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]