


!!!Listing 2 fu^r qt, 6/97
// ... Header-Dateien 

// Konstruktor fu^r farbiges Rechteck, 
// anfangs weis^.
ColorWidget::ColorWidget(QWidget *parent, const char *name )
        : QWidget( parent, name ) {
    r = b = g = 255;
}

// Slots fu^r Einstellung der Farbkomponenten
void ColorWidget::set_red(int red) {
  ColorWidget::setColor(red, g, b);
}

void ColorWidget::set_blue(int blue) {
  ColorWidget::setColor(r, g, blue);
}

void ColorWidget::set_green(int green) {
  ColorWidget::setColor(r,green, b);
}

//Private Methode zum Setzen aller drei Farbwerte
//Lo^st 'repaint()' aus, wenn sich die Farbe gea^ndert hat.
void ColorWidget::setColor(int red, int green, int blue) {
  if (r == red && b == blue && g == green)
    return;
  r = red;
  b = blue;
  g = green;
  repaint(FALSE);
}

// Von 'repaint()' ausgelo^stes Ereignis,
// fu^llt Rechteck mit der aktuellen Farbe
void ColorWidget::paintEvent( QPaintEvent *e) {
  QPainter p;
 
  p.begin(this);
  p.setBrush( QColor(r,g,b) );
  p.drawRect(0,0,width(),height());
  p.end();
}

// Klasse LineEditInt: Zuerst statische Klassenvariable
//                     fu^r ganzzahligen reg. Ausdruck definieren
//                     dann Konstruktoren
QRegExp LineEditInt::intRegexp = QRegExp("^[0-9]+$");

LineEditInt::LineEditInt(QRangeControl range,
			 QWidget *parent, const char *name) :
  QLineEdit(parent, name) {
  r = new QRangeControl(range.minValue(), range.maxValue(),
			range.lineStep(), range.pageStep(),
			range.value());
  init(r->value());
}

// Destruktor: Wenn QRangeControl existiert, freigeben
LineEditInt::~LineEditInt() {
  delete r;
}

// Gemeinsame Mini-Initialisierung aller LineEditInt-Konstruktoren:
// A^nderungen des Textfeldes mit 'setNum()' verbinden.
void LineEditInt::init(int v) {
  connect(this, SIGNAL(textChanged(const char *)), this, 
	  SLOT(setNum(const char *)));
  setNum(v);
}

// setNum: Aktualisiert ggfs. die lokale Kopie des Werts
// und schickt 'valueChanged'-Signal
void LineEditInt::setNum(int val) {
  int tmp;
  r->setValue(val);
  tmp = r->value();
  if (tmp == value)
    return;
  value = tmp;
  QString s;
  s.setNum(value);
  setText(s);
  emit valueChanged(value);
}

// 'Slot' setNum(): Akzeptiert den String nur,
// wenn er leer ist oder auf den ganzzahligen reg. Ausdruck
// pas^t. Entha^lt der String ein falsches Zeichen, setzt
// die Methode das Textfeld auf den letzten Wert zuru^ck
void LineEditInt::setNum(const char *s) {
  char str[20];
  QString qstr;
  if (strlen(s) == 0)
    return;
  if (intRegexp.match(s) == -1) {
    qstr.setNum(value);
    setText(qstr);
  } else {
    setNum(atoi(s));
  }
}


// Konstruktor: Nur ein Aufruf des Basisklassen-Konstruktors 
MyScrollBar::MyScrollBar(int min, int max, int stepValue,
 			 int stepPage, int value, 
 			 Orientation or, QWidget *parent,
 			 const char *name) :
   QScrollBar(min, max, stepValue, stepPage, value, or, parent, name) { 
}

// Slot 'setValue': Benutzt setValue() der Basisklasse nur, wenn sich
// der Wert gea^ndert hat. 

void MyScrollBar::setValue(int v) {
  if (v == value())
    return;
  QScrollBar::setValue(v);
}

    

int main( int argc, char **argv )
{
  static char *colorNames[3] = { "red", "green", "blue" };
  MyScrollBar *sb[3];
  LineEditInt *text[3];
  register int i;

  QApplication a( argc, argv );
  
  QGroupBox *box0 = new QGroupBox;
  box0->setFrameStyle( QFrame::Panel | QFrame::Sunken);
  QBoxLayout *b0_layout = new QBoxLayout( box0, QBoxLayout::LeftToRight,
					  10);
  for (i = 0; i < 3; i++) {
    QBoxLayout *s_layout = new QBoxLayout(QBoxLayout::BottomToTop);
    b0_layout->addLayout(s_layout,0);
    // Scrollbar und Textfeld fu^r ganze Zahlen erzeugen.
    sb[i]= new MyScrollBar(0,255,1,10,255,
			  QScrollBar::Vertical,box0, colorNames[i]);
    text[i] = new LineEditInt(QRangeControl(0,255,1,10,255),box0);
    // Farbe fu^r Textfeld einstellen (rot/gru^n/blau)
    QColorGroup cg = text[i]->colorGroup();
    QColorGroup new_cg(cg.foreground(), cg.background(),
		       cg.light(), cg.dark(), cg.mid(),
		       QColor(colorNames[i]), cg.base());
    text[i]->setPalette(QPalette(new_cg, new_cg, new_cg));
    // Im Textfeld den aktuellen Wert des Scrollbars anzeigen,
    // die maximale Textbreite setzen
    text[i]->setNum(sb[i]->value());
    text[i]->setMaxLength(3);
    text[i]->adjustSize();
    // Gro^s^en fu^r Textfeld und Scrollbar setzen und beide dem
    // Layout zur Verwaltung u^berreichen
    text[i]->setMaximumSize(text[i]->size());
    int w = label[i]->fontMetrics().width("999999");
    text[i]->setMinimumSize(w, text[i]->height());
    sb[i]->setMinimumSize(16,125);
    sb[i]->setMaximumSize(w+5,255); 
    s_layout->addWidget(sb[i]);
    s_layout->addWidget(text[i]);
  }
  // Rechteck fu^r Farbanzeige erzeugen und dem Layout u^berreichen
  ColorWidget cw(box0);
  cw.setMinimumSize(125,125); // Mindestens so gros^ wie Scrollbar
  b0_layout->addWidget(&cw,8);

  // Scrollbars und Textfelder per 'valueChanged'-Signal
  // miteinander verbinden
  for (i = 0; i < 3; i++) {
    sb[i]->connect(sb[i], SIGNAL(valueChanged(int)), 
		   text[i], SLOT(setNum(int)));
    text[i]->connect(text[i], SIGNAL(valueChanged(int)),
		      sb[i], SLOT(setValue(int)));
  }
  // Scrollbars mit dem Rechteck verbinden. 
  cw.connect(sb[0], SIGNAL(valueChanged(int)), &cw, SLOT(set_red(int)));
  cw.connect(sb[1], SIGNAL(valueChanged(int)), &cw, SLOT(set_green(int)));
  cw.connect(sb[2], SIGNAL(valueChanged(int)), &cw, SLOT(set_blue(int)));
  b0_layout->activate();
  // Applikation sichtbar machen und ihr Kontrolle u^bergeben
  box0->show();
  return a.exec();
