[linux-audio-dev] Re: MVC

Matthias Kretz Matthias.Kretz at urz.uni-heidelberg.de
Sat May 10 16:56:01 UTC 2003


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







-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: signature
URL: <http://lists.linuxaudio.org/pipermail/linux-audio-dev/attachments/20030510/58c9e23b/attachment-0003.pgp>


More information about the Linux-audio-dev mailing list