Seite 1 von 1

[gelöst] QTableWidgetItem nur Zahlen schreibar?

Verfasst: 13. Mai 2009 19:15
von forgoden
Hallo,

kann man irgendwie so konfigurieren dass man in einer Zelle einer Tabelle nur Zahlen reinschreiben kann? Also dass Buchstaben und andere Zeichen erst gar nicht erscheinen.

Oder geht das nur durch eine Überprüfung mit der Methode renewTable ?
Dass Buchstaben erscheinen, aber erst beim Returnen wieder verschwinden ist irgendwie unschön.

Verfasst: 13. Mai 2009 19:31
von upsala
Du suchst ein Delegate in der Doku.

Verfasst: 14. Mai 2009 10:53
von forgoden
stimmt. Sieht so aus dass es ganz anders ist als QTableWidgetItem ?
Also diese Zellen?

Mist, muss ich wieder alles umschreiben?

Verfasst: 14. Mai 2009 11:05
von franzf
Nö, nix umschreiben. Schau dir die Beispiele zu Q(Abstract)ItemDelegate an, schreib dir einen passenden und sorge dafür, dass dein Widget diesen verwendet.
Das sollte alles in der Doku stehen...
Schau dir auch das Kapitel "Delegate Classes" an.

Verfasst: 14. Mai 2009 16:07
von forgoden
funktioniert das nur mit QTableView?
Meins war QTableWidget. Dort

delegate.h und .cpp habe ich eingebunden aus diesem beispiel


jetzt wenn ich

Code: Alles auswählen

	SpinBoxDelegate delegate_;
    tableWidget->setItemDelegate(&delegate_);
    tableWidget->horizontalHeader()->setStretchLastSection(true);
mache. wird alles weiss (leer) angezeigt. Obwohl irgendwie noch Werte versteckt sind

edit: offenstlich funktioniert auch mit QTableView nicht

man so verwirrend, obwohl der code ziemlich exakt ist

edit2: okay es funktioniert nur in main()
aber nicht in der geerbten klasse von : public QWidget, private Ui::Macros

edit3: aaaargh es ist wegen dem hier!

Code: Alles auswählen

SpinBoxDelegate delegate;
hab ich vergessen als new zu erzeugen

edit4: aber es funktioniert nicht mit QTableWidget! wegen dem hier: tableWidget->setModel(model);

da kommt fehlermeldung:

Code: Alles auswählen

error C2248: "QTableWidget::setModel": Kein Zugriff auf private Member, dessen Deklaration in der QTableWidget-Klasse erfolgte.
        c:\qt\4.5.1\include\qtgui\../../src/gui/itemviews/qtablewidget.h(337): Siehe Deklaration von 'QTableWidget::setModel'
wieso ist das virtual definiert?
und wieso wird in Assistant QTableWidget kein setModel angezeigt obwohl diese dennoch in QTableWidget.h vorhanden ist?
hmm was soll ich jetzt machen?

Verfasst: 14. Mai 2009 17:56
von upsala
Es gibt Leute, die wollen die Doku lesen und es gibt welche die es nicht wollen...

Verfasst: 14. Mai 2009 18:58
von forgoden
ist aber viel text...

ich dachte man muss nicht umschreiben.
könnte man irgendwie mit casten austricksen?


glaub das wird mir zu kompliziert. will nicht alle felder spinbox machen
die 3. spalte soll doublespinbox sein

die vielen tableobjekte QModelIndex, QTableView, QAbstractTableModel, QStandardItemModel usw... bringen mir durcheinander. Gibt es überhaupt ne grafische Baumdarstellung von solchen Klassen?

Verfasst: 14. Mai 2009 19:40
von upsala
Naja, ich hätte den passenden Code (der fix und fertig für deinen Fall drinnensteht) einfach rauskopiert, aber du willst die Doku ja nicht lesen...

Verfasst: 14. Mai 2009 21:18
von forgoden
wozu gibt es schulen, universitäten und lehrer wenn man auch alles aus büchern lesen kann? ist doch totale steuerverschwendung :roll:

Verfasst: 14. Mai 2009 21:38
von franzf
Der Sinn der Schule ist ja auch nicht der Bücher zu ersetzen, sondern Schüler notfalls zu zwingen, sich ETWAS Bildung anzueignen sei es Geschichte, Mathe oder (gutes) Deutsch :P

Und die Doku ist auch nicht soooo umfangreich. (Sei froh dass du bei Qt eine solche Doku mit diesem Umfang hast und reg dich nicht drüber auf :P)

Es gibt bei jedem Thema immer auch Links zu "See also" Themen. irgendwann gehts nicht anders und du stolperst über ein kleines Beispiel, das "Color editor Factory" Example. Das kannst du wahrscheinlich 1:1,3 übernehmen. Viel Erfolg dabei :) (Alles andere wäre schon die Lösung, und hier wird keiner bezahlt, im Gegensatz zum Lehrer in der Schule...)

Verfasst: 14. Mai 2009 22:52
von forgoden
naja gelesen hab ich schon viel, aber englisch prägt nicht so

aber da ich in QTableWidget das gefunden hab:
If you want a table that uses your own data model you should use QTableView rather than this class.
muss ich wohl ein bißchen umbauen

Verfasst: 14. Mai 2009 22:55
von franzf
Les dir doch das Beispiel SAMT SOURCEN durch :(
setDefaultFactory setzen, und schon kannst du dein Delegate auch den Q*Widgets (nicht nur den Views) beibringen. Ganz ohne Model.

Verfasst: 14. Mai 2009 23:55
von forgoden
oh sorry, das hab ich nicht gecheckt oh man, glaub ich fokusiere irgendwie anders. "Color editor Factory" ganz übersehen

Verfasst: 16. Mai 2009 10:58
von franzf
Bevor du dich am Ende doch zu sehr verrennst, so könnte man es z.B. machen:

Code: Alles auswählen

#include <QtGui>

int main( int argc, char **argv )
{
    QApplication app( argc, argv );
    QItemEditorFactory *factory = new QItemEditorFactory;
    QItemEditorCreatorBase *intCreator = new QStandardItemEditorCreator<QSpinBox>();

    // Wenn noch keine Daten im Feld stehen, soll eine Spinbox aufgehen
    factory->registerEditor( QVariant::Invalid, intCreator );
    // Für ein int bitte eine SpinBox!
    factory->registerEditor( QVariant::Int, intCreator );

    QItemEditorFactory::setDefaultFactory( factory );

    QTableWidget table( 10, 5 );
    for( int i=3; i<9; i++ ) {
        for( int j=2; j<4; j++ ) {
            QTableWidgetItem *item = new QTableWidgetItem;
            item->setData( Qt::DisplayRole, i*j );
            table.setItem( i, j, item );
        }
    }
    table.show();
    return app.exec();
}
Beachte, dass nur Int und Invalid nen Editor bekommen. Solltest du auch noch Strings usw. haben wollen, musst du das noch selber ergänzen.

Grüße
Franz

Verfasst: 17. Mai 2009 11:30
von forgoden
ja danke. nach 3 tagen rumprobieren hab ichs auch endlich hingekriegt.
mein code ist etwas ähnlich. erst mal die Klasse SpinBoxDelegate:

Code: Alles auswählen

 class SpinBoxDelegate : public QSpinBox
 {
     Q_OBJECT
	  Q_PROPERTY(int value READ value WRITE setValue USER true)

 public:
     SpinBoxDelegate(QWidget *widget = 0);
hier z.b. soll value nur von 0 bis 3 gehen

Code: Alles auswählen

SpinBoxDelegate::SpinBoxDelegate(QWidget *widget) : QSpinBox(widget)
 {
	 setMaximum ( 3 );
 }
dann der code für den Editor:

Code: Alles auswählen

	QItemEditorFactory *factory = new QItemEditorFactory;
	QItemEditorCreatorBase *spinBoxCreator = new QStandardItemEditorCreator<SpinBoxDelegate>();
	factory->registerEditor(QVariant::Int, spinBoxCreator);
	QItemDelegate *delegat = new QItemDelegate;
	delegat->setItemEditorFactory(factory);
	tableWidget->setItemDelegate(delegat);
und beim erzeugen:

Code: Alles auswählen

QTableWidgetItem* cell4 = new QTableWidgetItem; 
cell4->setData(Qt::DisplayRole, 1 );
statt QItemEditorFactory::setDefaultFactory( factory );
habe ich hierfür

QItemDelegate *delegat = new QItemDelegate;
delegat->setItemEditorFactory(factory);
tableWidget->setItemDelegate(delegat);

geschrieben, damit das nicht global für alle Tabellen und Felder gelten. Das 2x doppelzeichen "::" steht für Global setzen wenn ich mich nicht Irre.

Was mir allerdings nicht so klar ist, wie ich in der selben Tabelle noch andere Editoren setzen kann. Denn cell4->setData(Qt::DisplayRole, 1 ); bestimmt nicht welchen Editor verwendet werden soll. Wenn ich z.b. zwei SpinBox-Editoren erzeuge, beide mit int-Typen und beide haben verschiedene maximum-, minimum-Werte nimmt er immer den letzten, wenn ich so schreibe:

Code: Alles auswählen

	QItemEditorCreatorBase *spinBoxCreator0 = new QStandardItemEditorCreator<SpinBox1000Delegate>();
	factory->registerEditor(QVariant::Int, spinBoxCreator0);
	QItemEditorCreatorBase *spinBoxCreator1 = new QStandardItemEditorCreator<SpinBoxDelegate>();
	factory->registerEditor(QVariant::Int, spinBoxCreator1);
	QItemEditorCreatorBase *spinBoxCreator2 = new QStandardItemEditorCreator<QDoubleSpinBox>();
	factory->registerEditor(QVariant::Double, spinBoxCreator2);
nur das mit doublespin box funktioniert, weil er wohl die unterschiedlichen QVariant unterscheiden kann.
Vlt. find ich das noch heraus (mit den Dokumenten :wink: )

Edit:

eine idee wäre:

wenn man abfragt welcher row angeklickt wird, erst dann ein entsprechender editor in registerEditor gesetzt wird

hmm mal versuchen...