Re: [linux-audio-dev] Re: MVC

New Message Reply About this list Date view Thread view Subject view Author view Other groups

Subject: Re: [linux-audio-dev] Re: MVC
From: Matthias Kretz (Matthias.Kretz_AT_urz.uni-heidelberg.de)
Date: Sat May 10 2003 - 23:23:45 EEST


On Saturday May 10 2003 14:41, Paul Davis wrote:
> here's a question to ask of a toolkit: can i set the depressed/raised
> state of a button programmatically, without implying that the user
> clicked it?

Let's look at a QPushButton as an example. The following slots are available:

void QButton::animateClick()
void QButton::toggle()
void QPushButton::setOn( bool )

and now some code:

QPushButton * b1 = new QPushButton( this );
QPushButton * b2 = new QPushButton( this );
b1->setToggleButton( true );
b2->setToggleButton( true );
connect( b1, SIGNAL( toggled( bool ) ), b2, SLOT( setOn( bool ) ) );
connect( b2, SIGNAL( toggled( bool ) ), b1, SLOT( setOn( bool ) ) );

You might expect, that this would result in an infinite loop but actually the
toggled signal is only emitted if the button was really toggled. So calling
setOn( true ) on a already "on" button won't change it's state so it won't
emit the according signals.

This is not exactly what you asked for, but you might want to use signal
blocking or disconnect a signal and slot in the case where you want to set
the value of a widget without calling the code that would be called if the
user had input that value.

> then ask the same question of value indicator widgets. etc.

dunno. If I set the value of a "value indicator widget" nothing bad would
happen, no? I have the feeling I didn't get your question :-)

> yes, its a widely known moniker, but its not a widely used practice. i
> know that in GTK+, you have to basically be willing to tolerate
> feedback loops between the model and the view, so that when one is
> changed, the other gets changed, which might change the first one
> again, etc. heaven help you if you suffer from rounding issues between
> the model and the view, because then you have no way to stop the loop
> without a deadful kludge. without rounding issues, you have to do lots
> of this sort of thing:
>
> handler_for_some_gui_event (...) {
> if (state_of_view != state_of_model) {
> change_view ();
> }
> }

How about:

class View
{
  public slots:
    void setValue( int value );
  signals:
    void valueChanged( int value );
  private:
    int _value;
};

class Model
{
  public:
    Model();
  private slots:
    void viewChanged( int value );
  private:
    View *_view1, *_view2;
}

View::setValue( int value )
{
  if( _value != value )
  {
    _value = value;
    emit valueChanged( _value );
  }
}

Model::Model()
{
  _view1 = new View();
  _view2 = new View();
  connect( _view1, SIGNAL( valueChanged( int ) ),
           this, SLOT( viewChanged( int ) ) );
  connect( _view2, SIGNAL( valueChanged( int ) ),
           this, SLOT( viewChanged( int ) ) );
}

Model::viewChanged( int value )
{
  // update the value of the views and don't care to handle it (since we're
  // already doing it ;-) )
  view1->blockSignals( true );
  view2->blockSignals( true );
  view1->setValue( value );
  view2->setValue( value );
  view1->blockSignals( false );
  view2->blockSignals( false );
}

-- 
C'ya
        Matthias
________________________________________________________
Matthias Kretz (Germany)                          <><
http://Vir.homeip.net/
MatthiasKretz_AT_gmx.net, kretz_AT_kde.org,
Matthias.Kretz_AT_urz.uni-heidelberg.de



New Message Reply About this list Date view Thread view Subject view Author view Other groups

This archive was generated by hypermail 2b28 : Sat May 10 2003 - 23:33:43 EEST