Re: [gtkmm] Communicating with other windows - help



Luka Napotnik <nluka email si> writes:

> I'm kind of new in gtkmm programming and I honestly don't know how to
> communicate between two windows.
>
> I have this main window that has an add button. That button opens a
> new window. The new window has entry boxes. Now I want to transform
> the information from the add widnow to the main window. In the gtkmm
> tutorial I read to use signals but I don't understand that

The main thing you need to do is separate the user interface from the
data that it operates on.

Have you read about the Model-View-Controller and Model-View-Presenter
patterns?  For example:

http://www.swtech.com/cgi/dlxgotores.cgi?r=905257819
http://c2.com/cgi/wiki?ModelViewController
http://www.object-arts.com/EducationCentre/Overviews/MVC.htm
http://ootips.org/mvc-pattern.html
http://c2.com/cgi/wiki?ModelViewPresenter
http://www.object-arts.com/EducationCentre/Overviews/ModelViewPresenter.htm

Make sure you store the data in a "model" class.  For example:

class model : public Glib::Object
{
 private:
   Glib::Property<Glib::ustring> property_name;

 public:
   /// Proxy for the "name" property.
   Glib::PropertyProxy<Glib::ustring> property_name();
}

This could also be a normal struct, or a class from another library.
The important part is that it should emit a signal when individual
members, or the object as a while, changes.  This could be a libsigc++
signal, in the above case property_name().signal_changed().  I often
use my own smartpointer class, which emits a changed signal when the
contained object is changed (for models which are not aware of Gtk or
Glib).

The "view" part is a view on the model.  For example, in this case it
could be a label in the main window, or an entry field in a dialogue
box.  When it detects a "changed" signal from the model, it must
refresh itself to represent the current state of the model.  For
example:

  view::on_name_changed()
  {
    entry->set_text(model.property_text());
  }

The "presenter" part is responsible for changing the model, for
example after you press enter or leave an entry widget.  It might do
some validation of the data in addition.  For example:

  view::on_name_entry_activated()
  {
    model.property_text() = entry->get_text();
  }

Because of this separation, it's possible to have several views on the
same model.  In your case, your main window and entry window, which
will share the same model.  This has many advantages.  Consider that
when you make a change to the entry window, the model will be updated
which will trigger the main window view to be updated automatically.
Since you can make a copy of the model before displaying the dialogue,
if the user clicks "Cancel", restoring the previous state is as simple
as

  model saved_model(real_model);
  viewdialog(real_model);
  if (viewdialog.run() == Gtk::RESPONSE_CANCEL)
    real_model = saved_model;

since the old values will be restored and changed signals emitted to
update the view(s).

What I would do is specify the model in the dialogue constructor, for
example:

class viewdialog : public Gtk::Dialog
{
 public:
   viewdialog(model& model_reference);
}

(The view and presenter are combined in the form of the dialogue,
which has methods to refresh the view (on_name_changed()) and to
change the model (on_name_entry_activated() and
on_name_entry_focus_out()).  I'm not sure if this is the recommended
practice--is there a better way?

One last point: if you derive a new model from your existing model
class, you can use it with the same view, providing you make the
appropriate functions virtual.  Likewise, you can derive a new views
from your view class, to for example to display subsets of the model
information in different ways.


A practical example: in a Gtkmm interface I am writing currently, I
allow the user to create buttons and place them in a Gtk::Table.  The
user can customise the buttons as they wish, including:
- background colour
- text colour
- text font
- the text string
These properties are stored in a class ButtonProperties.  The button
that displays these properties is a /view on/ these properties.  When
the user right-clicks the button and selects "Properties", the
properties dialogue is another /view on/ the same ButtonProperties,
which allows the user to change the properties.  Changes to the
properties dialogue are immediately reflected in the parent window in
the "button view".

Also have a look at the TreeView/TreeModel and TextView/TextBuffer
which are model/view widgets and data stores provided by Gtk.


I'm still learning this stuff myself, so if there are any flaws in my
understanding, I'd appreciate any corrections.

Regards,
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]