QPushButton erweitern

Alles rund um die Programmierung mit Qt
Antworten
mkpls
Beiträge: 2
Registriert: 23. September 2006 11:23

QPushButton erweitern

Beitrag von mkpls »

Hallo,
ich benötige für ein ein Projekt einen QPushButton mit Sondereigenschaft. Das Button soll selbst noch eine ID haben, die bei dem clicked-SIGNAL mit zurückgeliefert werden soll um so in der Ergeignisbehandlung feststellen zu können, von welchem den der Buttons das Signal kam. Dazu haben ich folgendes probiert:

mydialog.h

Code: Alles auswählen

#ifndef MYBUTTON_H
#define MYBUTTON_H
#include <QPushButton>
class MyButton : public QPushButton{
	Q_OBJECT
	
	public:
		MyButton(unsigned int cn, QWidget *parent = 0);

	signals:
		void clicked(unsigned int);
	
	public slots:
		void click();
	
	private:
		unsigned int id;
};
#endif
mybutton.cpp

Code: Alles auswählen

#include "mybutton.h"
#include <QPushButton>
#include <iostream>

MyButton::MyButton(unsigned int cn, QWidget *parent): QPushButton(parent){
	id = cn;
	setText(QString::number(id));

}

void MyButton::click(){
	std::cout << id << std::endl;
	emit clicked(id);
}
Um die Sache zu testen:

Code: Alles auswählen

#include "testdialog.h"
#include "mybutton.h"
#include <QApplication>
#include <QDialog>
#include <QPushButton>
#include <QGridLayout>

#include <iostream>

TestDialog::TestDialog(QWidget *parent):QDialog (parent) {

	QGridLayout *layout = new QGridLayout(this);

	unsigned int row = 0;
	unsigned int col = 0;

	ButtonArray = new (MyButton*[15]);

	for (unsigned int i = 0; i < 16; i ++) {
		ButtonArray[i] = new MyButton(i, this);
		layout->addWidget(ButtonArray[i], row, col);
		QObject::connect(ButtonArray[i], SIGNAL(clicked(unsigned int)), this, SLOT(out(unsigned int)));
		col++;
		if (col == 5) {
			col = 0;
			row++;
		}
	}

	ButtonClose = new QPushButton ("Close", this);
	layout->addWidget(ButtonClose, row, col);
	QObject::connect(ButtonClose, SIGNAL (clicked()), qApp, SLOT(quit()));


}

void TestDialog::out(unsigned int i){
	std::cout << "clicked: id = "<< i  << std::endl;

}

Leider geht es nicht das der Button beim Click seine ID ausgibt. Die Sachen aus der iostream werden wieder entfernt. Ich will nur erstmal einen Button mit dieser Funktion hinbekommen.

Hat jemand Vorschläge zur Lösung?
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

Was genau geht nicht? Siehst du nur die Ausgabe nicht (-> CONFIG += console) oder hast du mit dem Debugger nachgeschaut und gesehen dass er dort nicht ankommt?

/edit: Ausserdem glaube ich nicht, dass click() aufgerufen wird wenn der Button gedrückt wird. Man muss wohl singal clicked() abfangen...
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
Uwe
Beiträge: 176
Registriert: 9. Oktober 2005 13:37
Wohnort: München

Beitrag von Uwe »

Stecke Deine Buttons in eine QButtonGroup und verwende "void QButtonGroup::buttonClicked ( int id )"

HTH,
Uwe
mkpls
Beiträge: 2
Registriert: 23. September 2006 11:23

Beitrag von mkpls »

Die Augabe ist sichtbar(ich hab einfach das normale clicked()-SIGNAL mit einer Parameterfreien Routine out Verbunden und da wird mir was angezeigt). Es geht die gesamte Ereignisfolge nicht.
Das mit der ButtounGroup nützt mir nix, da es auch mal Strings als ID sein können.

Ich hab jetzt mal das

Code: Alles auswählen

QObject::connect(this, SIGNAL(clicked()), this, SLOT(click()));
in den Konstruktor von MyButton eingefügt und damit geht es. Aber es muss doch auch ohne diesen Umweg möglich sein dort Routinen zur Ergeignisbehandlung zu überladen.
DarkWotan
Beiträge: 65
Registriert: 18. Mai 2006 10:03

Beitrag von DarkWotan »

Ist ungefähr das das, was du meinst oder machen möchtest?:

mybutton.hpp:

Code: Alles auswählen

#ifndef MYBUTTON_HPP
#define MYBUTTON_HPP

#include <QString>
#include <QWidget>
#include <QPushButton>

class MyButton : public QPushButton
{
  Q_OBJECT

  public:
  MyButton(const QString& text, int id, QWidget* parent = NULL);
  MyButton(const QString& text, QWidget* parent = NULL);
  
  private:
  static int nextId;
  int m_id;
  
  public slots:
  //click() überschreiben
  void click();
  
  signals:
  //ein neues Signal hinzufügen
  void clicked(int id);  
};

#endif
mybutton.cpp:

Code: Alles auswählen

#include "mybutton.hpp"

int MyButton::nextId = 0;

MyButton::MyButton(const QString& text, int id, QWidget* parent)
  : QPushButton(text, parent), m_id(id)
{
  //das alte clicked()-Signal muss mit dem neuen click()-Slot verbunden werden
  connect(this, SIGNAL(clicked()), this, SLOT(click()));
}

MyButton::MyButton(const QString& text, QWidget* parent)
  : QPushButton(text, parent), m_id(nextId++)
{
  connect(this, SIGNAL(clicked()), this, SLOT(click()));
}

void MyButton::click()
{
  //bloß nicht die Supermethode aufrufen, da diese wieder das Auslösen des Signals clicked() zur Folge hätte -> Endlos-Rekursion
  //QPushButton::click();

  //sobald der Slot "ausgelöst" wurde, muss ein neues Signal mit der ID verschickt werden
  emit clicked(m_id);
}
mywindow.hpp:

Code: Alles auswählen

#ifndef MYWINDOW_HPP
#define MYWINDOW_HPP

#include <QWidget>

class MyButton;

class MyWindow : public QWidget
{
  Q_OBJECT

  public:
  MyWindow(QWidget* parent = NULL);
  
  private:
  MyButton* myButton[3];
  
  public slots:
  //dieser Slot kümmert sich um die Ausgabe
  void out(int id);
};

#endif
mywindow.cpp:

Code: Alles auswählen

#include "mywindow.hpp"
#include "mybutton.hpp"

#include <QtCore>
#include <QtGui>

MyWindow::MyWindow(QWidget* parent)
  : QWidget(parent)
{
  myButton[0] = new MyButton(tr("Click me"));
  myButton[1] = new MyButton(tr("And me, too"));
  myButton[2] = new MyButton(tr("Don't forget me"));
  
  QHBoxLayout* layout = new QHBoxLayout(this);
  
  for (int i = 0; i < 3; ++i)
  {
    layout->addWidget(myButton[i]);
    //wir verbinden das neue clicked()-Signal mit unserem Ausgabe-Slot
    connect(myButton[i], SIGNAL(clicked(int)), this, SLOT(out(int)));
  }
}

void MyWindow::out(int id)
{
  QMessageBox::information(this, tr("Something has happened..."),
                           QString(tr("Button ID: %1")).arg(id),
                           QMessageBox::Ok);
}
MfG, Cedric
Zuletzt geändert von DarkWotan am 23. September 2006 13:34, insgesamt 2-mal geändert.
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

mkpls hat geschrieben: in den Konstruktor von MyButton eingefügt und damit geht es. Aber es muss doch auch ohne diesen Umweg möglich sein dort Routinen zur Ergeignisbehandlung zu überladen.
Da die Funktion click() keine Ereignisfunktion ist (und Du sie im Grunde falsch verwendest, siehe http://doc.trolltech.com/4.1/qabstractbutton.html#click), muss man schon das signal clicked() abfangen und seine Funktionen, die man haben möchte, hinzufügen...
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
Antworten