QTableWidget per Buttonclick mit Inhalt aus QLineEdit 's

Verschiedenes zu Qt
Antworten
Jannilein
Beiträge: 19
Registriert: 13. Juni 2014 13:38

QTableWidget per Buttonclick mit Inhalt aus QLineEdit 's

Beitrag von Jannilein »

Hallo, ich habe folgendes Problem :
Ich möchte das der Name und die Value bei einem Klick auf den Button unten in die Tabelle eingefügt werden nach einander.
Also beim ersten einfügen soll es in die Erste reihe in Spalte 1 und Spalte 2.
Beim 2. einfügen soll es in die 2. Reihe in die erste und 2. Spalte.
Danach ( ehr 2. rangig,) sollen diese Einträge von der Tabelle sotiert werden.
Wie mache ich das, das diese Einträge Nacheinander in die Tabelle kommen ?
Wie man es manuell macht ( pTable . setItem (1 , 1 , QTableWidgetItem( " 1910 " ) ); ) ist NICHT gefragt, sondern wie es das selbstständig hoch zählt und dann den Text aus den Edit's ausließt und einfügt.
Ich dachte irgendwie daran das da wo die einsen nun stehen, ich einfach einen int Wert namens i einsetze und i nach jedem aufruf der Klick methode erhöhe, soweit die Theorie.
Ich bin kann die Basic's von c++ , java & will mich nun mit QT auseinander setzen.

meine QLineEdit Felder heißen txtName und txtValue .
Die includes habe ich nun nich mit reinkopiert

in der header ist einfach nur "void pushButtonClicked();" drinn

gerne könnt ihr mir auch tipps geben, wie ich das besser ordne etc.
Danke :)!!

Code: Alles auswählen

// AufgabeMain.cpp

#include "Aufgabe.h"




int main (int argc, char* argv[])
{
	QApplication myapp(argc,argv);
	QWidget window;

		QWidget* mywidget = new QWidget();

	mywidget->setGeometry(800,400,800,650);

	QLabel* lblname = new QLabel ("Name: ", mywidget );

	lblname->setGeometry (40 , 50 , 250 , 60);
	lblname->setFont(QFont("Times", 10, QFont::Bold));

	QLineEdit *txtname = new QLineEdit();
	txtname->show();
	QString strname ;
	strname = ( txtname ->text ());


	QLabel* lblvalue = new QLabel("Value",mywidget);
	lblvalue->setGeometry (40 , 50 , 250 , 60);
	lblvalue->setFont(QFont("Times", 10, QFont::Bold));
	QLineEdit *txtvalue = new QLineEdit();
	txtvalue->show();
	QString strvalue ;
	strvalue = ( txtvalue ->text ());

	QPushButton* btnaddtotable = new QPushButton( "Add to Table", mywidget);

	btnaddtotable->setGeometry(50,20,400,40);

	QObject::connect ( btnaddtotable, SIGNAL ( pressed() ), &myapp , SLOT(pushButtonClicked())) ;

	 QTableWidget* table = new QTableWidget(mywidget);

	table->setRowCount( 10 );
  table->setColumnCount( 2 );
  table->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding );

  QStringList hLabels, vLabels;
  hLabels << "Name" << "Value" ;
  table->verticalHeader()->setVisible( false );
  table->setHorizontalHeaderLabels( hLabels );

	QVBoxLayout *layout = new QVBoxLayout (&window);
	layout->addWidget(lblname);
	layout->addWidget(txtname);
	layout->addWidget(lblvalue);
	layout->addWidget(txtvalue);
	layout->addWidget(btnaddtotable);
	layout->addWidget(table);
 
  table->show();
  window.show();

Code: Alles auswählen

// Aufgabe.cpp

#include "Aufgabe.h"
#include "AufgabeMain.cpp"
int i ;

void Aufgabe:: pushButtonClicked( )
{	 
	
	
}

archer
Beiträge: 306
Registriert: 2. Februar 2006 09:56

Re: QTableWidget per Buttonclick mit Inhalt aus QLineEdit 's

Beitrag von archer »

Du könntest z.B. mit rowCount() arbeiten.
Die Tabelle mit 0 Zeilen und 2 Spalten erzeugen und dann in deinem click() Slot eine neue Zeile einfügen.

Code: Alles auswählen

int Row = mpMyTable->rowCount();
mpMyTable->insertRow(Row );
...
Ich würde allerdings auch nicht alles so in die main() schreiben. Trenne lieber deine Oberfläche davon
und mach eine eigene Klasse dafür.
Jannilein
Beiträge: 19
Registriert: 13. Juni 2014 13:38

Re: QTableWidget per Buttonclick mit Inhalt aus QLineEdit 's

Beitrag von Jannilein »

archer hat geschrieben:Du könntest z.B. mit rowCount() arbeiten.
Die Tabelle mit 0 Zeilen und 2 Spalten erzeugen und dann in deinem click() Slot eine neue Zeile einfügen.

Code: Alles auswählen

int Row = mpMyTable->rowCount();
mpMyTable->insertRow(Row );
...
Ich würde allerdings auch nicht alles so in die main() schreiben. Trenne lieber deine Oberfläche davon
und mach eine eigene Klasse dafür.
Danke, ja das habe ich gestern auch gemacht, also die Main ausgelagert.
Wie meinst du das denn ? Also ich schreibe in dem click Slot das : int Row = mpMyTable->rowCount();
mpMyTable->insertRow(Row ); halt mit meinen bezeichnungen ?

Also int Row = table-> rowCount()
table->insertRow(Row); ?
Und das macht eine neue Zeile in der Tabelle ? Weil meine Frage war ja, wie man das hinbekommt, das ich überhaubt die werte in die verschiedenen Zeilen und Spalten bekomme.
Dankeschön :)
archer
Beiträge: 306
Registriert: 2. Februar 2006 09:56

Re: QTableWidget per Buttonclick mit Inhalt aus QLineEdit 's

Beitrag von archer »

Das steht doch in der Dokumentation zu QTableWidget, sogar mit Beispielcode.

Code: Alles auswählen

int Row = mpMyTable->rowCount();
mpMyTable->insertRow(Row);

QTableWidgetItem* pNameItem = new QTableWidgetItem("Name");
mpMyTable->setItem(Row, 0, pNameItem);

QTableWidgetItem* pValueItem = new QTableWidgetItem("Value");
mpMyTable->setItem(Row, 1, pValueItem);
Jannilein
Beiträge: 19
Registriert: 13. Juni 2014 13:38

Re: QTableWidget per Buttonclick mit Inhalt aus QLineEdit 's

Beitrag von Jannilein »

Okey , das is mein Aktueller Code , ich stehe immernoch etwas auf dem schlauch glaube ich , aber imoment stürzt es beim ausführen immer ab und sagt : Eine Ausnahme (erste Chance) bei 0x64c0f980 in Tester.exe: 0xC0000005: Zugriffsverletzung beim Lesen an Position 0x00000000.
Unbehandelte Ausnahme bei 0x64c0f980 in Tester.exe: 0xC0000005: Zugriffsverletzung beim Lesen an Position 0x00000000.
Das Programm "[5148] Tester.exe: Systemeigen" wurde mit Code -1073741510 (0xc000013a) beendet.

was soll ich dagegen machen ?
Hier meine Header :

Code: Alles auswählen

	#ifndef _TABELLE_H_
#define _TABELLE_H_
 
class Tabelle : public QWidget
{
    Q_OBJECT   
 
public:
    Tabelle(void);
    void init();
    QString strname ;
    QString strvalue;
    QWidget *window;
    QTableWidget* table;
    int row;
    QWidget* mywidget;
 
public slots:
 
    void pushButtonClicked();
};
#endif	

Hier meine Main ( ohne includes ) :

Code: Alles auswählen

	#include "Tabelle.h"
 
 int main (int argc, char* argv[])
{
     QApplication myapp(argc,argv);
    Tabelle tabelle;
     tabelle.init();
return myapp.exec();
 
}	

Code: Alles auswählen

Hier meine Tabelle.cpp
	#include "Tabelle.h"
 
Tabelle::Tabelle()
{
    //empty
}
 
 void Tabelle::init()
{
     QWidget* mywidget = new QWidget();
    // instantiierung einesQQ-pllication objects, das ist immer nötig.
 
    QTableWidget* table = new QTableWidget();
     QLabel* lblname = new QLabel ("Name: ", mywidget );
     QLineEdit *txtname = new QLineEdit();
     QLabel* lblvalue = new QLabel("Value",mywidget);
     QLineEdit *txtvalue = new QLineEdit();
     QPushButton* btnaddtotable = new QPushButton( "Add to Table", mywidget);
     QVBoxLayout *layout = new QVBoxLayout (mywidget);
 
     QString strname ;
    strname = ( txtname ->text ());
 
   
    QString strvalue ;
    strvalue = ( txtvalue ->text ());
 
     table->setRowCount( 10 );
     table->setColumnCount( 2 );
 
      table->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding );
    // Labels setzen
   QStringList hLabels, vLabels;
   hLabels << "Name" << "Value" ;
   table->verticalHeader()->setVisible( false );
   table->setHorizontalHeaderLabels( hLabels );
   lblname->setGeometry (40 , 50 , 250 , 60);
    lblname->setFont(QFont("Times", 10, QFont::Bold));
    lblvalue->setGeometry (40 , 50 , 250 , 60);
    lblvalue->setFont(QFont("Times", 10, QFont::Bold));
    btnaddtotable->setGeometry(50,20,400,40);
     mywidget->setGeometry(800,400,800,650);
 
    layout->addWidget(lblname);
    layout->addWidget(txtname);
    layout->addWidget(lblvalue);
    layout->addWidget(txtvalue);
    layout->addWidget(btnaddtotable);
    layout->addWidget(table);
    QTableWidgetItem * item = new QTableWidgetItem(0);
    item->setText(strname);
    QTableWidgetItem * item2 = new QTableWidgetItem(0);
    item->setText(strvalue);
   
    table->setItem( row , 1 , item);
    table->setItem( row  , 2 , item2);
    QObject::connect ( btnaddtotable, SIGNAL ( clicked() ), this , SLOT(pushButtonClicked())) ;
 
    mywidget->show();
     
    txtname->show();
    txtvalue->show();
}
 
void Tabelle::pushButtonClicked()
{  
    int rowcount = 1;
    rowcount = table->rowCount();
    row = 1 ;
 
    if (  row > rowcount )
    {
        table->insertRow( table->rowCount() );
        row++;
    }  
} 
archer
Beiträge: 306
Registriert: 2. Februar 2006 09:56

Re: QTableWidget per Buttonclick mit Inhalt aus QLineEdit 's

Beitrag von archer »

Hast du dein Programm schon mal im Debugger gestartet?

Warum erzeugst du in Tabelle das QWidget widget? Tabelle ist doch schon ein QWidget.
Du kannst den Code von init() auch schon im Konstruktor ausführen.

Wenn du in init() table->setItem() aufrufst, welchen Wert hat dort row?
Initialisiere deine Klassenmember im Konstruktor.

Die Zeile table->verticalHeader()->setVisible( false ); solltest du auch mal prüfen.
Liefert table->verticalHeader() eventuell NULL zurück? Zugriffverletzung!

Du solltest dich auch nochmal mit der Gültigkeit von Variablen beschäftigen oder allgemein
mit c++ Grundlagen.
In pushButtonClicked() crasht es garantiert beim Zugriff auf den zeiger table.
Jannilein
Beiträge: 19
Registriert: 13. Juni 2014 13:38

Re: QTableWidget per Buttonclick mit Inhalt aus QLineEdit 's

Beitrag von Jannilein »

archer hat geschrieben:Hast du dein Programm schon mal im Debugger gestartet?

Warum erzeugst du in Tabelle das QWidget widget? Tabelle ist doch schon ein QWidget.
Du kannst den Code von init() auch schon im Konstruktor ausführen.

Wenn du in init() table->setItem() aufrufst, welchen Wert hat dort row?
Initialisiere deine Klassenmember im Konstruktor.

Die Zeile table->verticalHeader()->setVisible( false ); solltest du auch mal prüfen.
Liefert table->verticalHeader() eventuell NULL zurück? Zugriffverletzung!

Du solltest dich auch nochmal mit der Gültigkeit von Variablen beschäftigen oder allgemein
mit c++ Grundlagen.
In pushButtonClicked() crasht es garantiert beim Zugriff auf den zeiger table.
Also kann ich statt mywidget auch this schreiben ?
Ja, aber mein Chef möchte nich das der Konstruktor damit aufgebläht wird, hatte ich vorher auch darin.

Wieso crasht es denn bei dem Zugriff mit table ? es müsste doch gehen sonst würde es doch nich angezeigt werden wenn man Strg + Leertaste drückt ?!
Es geht auch nicht wenn ich die ganze zeile von verticalHeader auskommentiere. Mein Aktueller Quellcode und es geht immernochnicht :

Code: Alles auswählen

#ifndef _TABELLE_H_
#define _TABELLE_H_

class Tabelle : public QWidget
{
	Q_OBJECT	

public:
	Tabelle(void);
	void init();
	QString strname ;
	QString strvalue;
	QWidget *window;
	QTableWidget* table;
	int row;
	int rowcount;
	QLineEdit *txtname;
	QLineEdit *txtvalue;
public slots:
    void pushButtonClicked();
};
#endif
[code]
#include "Tabelle.h"

Tabelle::Tabelle()
{
QString strname = "strname";
QString strvalue = "strvalue";
int rowcount = 1;
int row = 1;
QLineEdit *txtname = new QLineEdit();
QLineEdit *txtvalue = new QLineEdit();

}

void Tabelle::init()
{
QTableWidget* table = new QTableWidget();
QLabel* lblname = new QLabel ("Name: ", this );
QLabel* lblvalue = new QLabel("Value",this);
QPushButton* btnaddtotable = new QPushButton( "Add to Table", this);
QVBoxLayout *layout = new QVBoxLayout (this);
table->setRowCount( 10 );
table->setColumnCount( 2 );
table->setSizePolicy( QSizePolicy::Expanding, QSizePolicy::Expanding );
// Labels setzen
QStringList hLabels, vLabels;
hLabels << "Name" << "Value" ;
//table->verticalHeader()->setVisible(false);
table->setHorizontalHeaderLabels( hLabels );
lblname->setGeometry (40 , 50 , 250 , 60);
lblname->setFont(QFont("Times", 10, QFont::Bold));
lblvalue->setGeometry (40 , 50 , 250 , 60);
lblvalue->setFont(QFont("Times", 10, QFont::Bold));
btnaddtotable->setGeometry(50,20,400,40);
this->setGeometry(800,400,800,650);

layout->addWidget(lblname);
layout->addWidget(txtname);
layout->addWidget(lblvalue);
layout->addWidget(txtvalue);
layout->addWidget(btnaddtotable);
layout->addWidget(table);

QObject::connect ( btnaddtotable, SIGNAL ( clicked() ), this , SLOT(pushButtonClicked())) ;

this->show();
txtname->show();
txtvalue->show();

}

void Tabelle::pushButtonClicked()
{ rowcount = table->rowCount();
if ( row > rowcount )
{
table->insertRow( table->rowCount() );
row++;
}
strname = ( txtname ->text ());
strvalue = ( txtvalue ->text ());
QTableWidgetItem * item = new QTableWidgetItem(0);
item->setText(strname);
QTableWidgetItem * item2 = new QTableWidgetItem(0);
item->setText(strvalue);
table->setItem( row , 1 , item);
table->setItem( row , 2 , item2);
}
[/code]
archer
Beiträge: 306
Registriert: 2. Februar 2006 09:56

Re: QTableWidget per Buttonclick mit Inhalt aus QLineEdit 's

Beitrag von archer »

Schau dir mal deinen jetzigen Konstruktor an. Was machst du da?
Du erzeugst unter anderem ein QLineEdit:

Code: Alles auswählen

QLineEdit *txtname = new QLineEdit();
Dieses LineEdit schwirrt jetzt irgendwo herum. Und du fässt es nie wieder an.
Im Header hast du zwar einen Member der auch txtname heist, der aber nicht mit dem
im Konstruktor gemeinsam hat. In Init() fügst du jetzt ein Element txtname ein, das garnicht existiert.
Informiere dich über die Gültigkeit von Variablen und die Grundlagen von C++.
Wenn du den Member verwenden willst muß deine Zeile im Konstruktor

Code: Alles auswählen

txtname = new QLineEdit();
heißen.

Dein Code muß z.B. so aussehen:

Code: Alles auswählen

Tabelle::Tabelle()
{
    strname = "strname";
    strvalue = "strvalue";
    rowcount = 1;
    row = 0; 
    txtname = new QLineEdit();
    txtvalue = new QLineEdit();
}
Den Rest mußst du selber lösen! Mit ein paar kleinen Korrekturen in init() und in pushButtonClicked()
läuft dein Programm ohne Probleme.
Jannilein
Beiträge: 19
Registriert: 13. Juni 2014 13:38

Re: QTableWidget per Buttonclick mit Inhalt aus QLineEdit 's

Beitrag von Jannilein »

Danke, ja das habe ich nun auch vestanden, dadurch lege ich ein ganz neues an, anstatt das aus dem header zu nutzen.
Mein prg funktioniert nun soweit, danke :)
Also ich kann wenn ich auf den button klicke der reihe nach die namen zsm mit den values einfügen und wenn keine Zeilen mehr da sind, macht er neue wo die neuen Inhalte dann reinkommen.
Das ist schonmal ein erstes Erfolgserlebnis * stolz* .

Ich soll nun aber noch eine sortierfunktion reinbringen, die wenn man auf einen Sort button klickt, es nach dem Namen sortiert, aber die Values müssen immer bei dem dazugehörigem namen bleiben.
zudem soll dann noch verhindert werden, das man am ende 2x den selben Namen hat, also das eingegebene mit allen bereits bestehenden Namen vergleichen. Wenn schon eins mit dem Namen existiert, soll es nicht hinzugefügt werden.
Zum ersterem habe ich im Internet " void QTableWidget sortItems (int column , Qt::SortOrder order=Qt::AscendingOrder ) " gefunden.
die Parameter jedoch sind für mich etwas unklar. Also Colum ist klar , dann überschreibt man die SortOrder Methode von QT . Aber was ist denn " AscendingOrder" ?
Ascending bedeutet ja aufsteigend also denke ich mal das es eine Aufsteigende Sortierung ist, aber wo gebe ich an, das es von A nach Z sortieren soll ?

Ich nehme an, das ich hier nur die Methode Definiere, aber wie sortiere ich denn nach Alphabet und vorallem so, das die Value mit dem Namen mit dem man ihn zsm in die Tabelle eingefügt hat, zusammen bleibt ?
Dann gibt es ja noch "setSortingEnabled (true);" muss man das auf true setzen, damit alle Items aus der Tabelle sortierbar sind ?
archer
Beiträge: 306
Registriert: 2. Februar 2006 09:56

Re: QTableWidget per Buttonclick mit Inhalt aus QLineEdit 's

Beitrag von archer »

Lies die Dokumentation von Qt.
Qt::SortOrder ist dort doch beschrieben!
Probier das Sortieren einfach aus, dann wirst du sehen was alles sortiert wird.

Das mit den doppelten Namen wirst du selber implementieren müssen.
Alle Zeilen durchgegen und prüfen ob der Name schon da ist.
Jannilein
Beiträge: 19
Registriert: 13. Juni 2014 13:38

Re: QTableWidget per Buttonclick mit Inhalt aus QLineEdit 's

Beitrag von Jannilein »

archer hat geschrieben:Lies die Dokumentation von Qt.
Qt::SortOrder ist dort doch beschrieben!
Probier das Sortieren einfach aus, dann wirst du sehen was alles sortiert wird.

Das mit den doppelten Namen wirst du selber implementieren müssen.
Alle Zeilen durchgegen und prüfen ob der Name schon da ist.
Ja aber ich weiß nicht , was ich in die Methode rein schreiben muss , wenn ich auf QT das im Quellcode anzeigen lassen will, finde ich die Methodendeklaration, aber nicht die implementation.
archer
Beiträge: 306
Registriert: 2. Februar 2006 09:56

Re: QTableWidget per Buttonclick mit Inhalt aus QLineEdit 's

Beitrag von archer »

Was du machen mußt steht in der Dokumentation, nicht im Quellcode!
Beispiel Qt::SortOrder:

Code: Alles auswählen

Qt::AscendingOrder	0	The items are sorted ascending e.g. starts with 'AAA' ends with 'ZZZ' in Latin-1 locales
Qt::DescendingOrder	1	The items are sorted descending e.g. starts with 'ZZZ' ends with 'AAA' in Latin-1 locales
Einfaches sortieren:
Wir ergänzen die init() Methode mit

Code: Alles auswählen

table->horizontalHeader()->setSortIndicatorShown(true);
table->setSortingEnabled(true);
connect(table->horizontalHeader(), SIGNAL(sortIndicatorChanged(int, Qt::SortOrder)),
             this,  SLOT(sortIndicatorChanged(int, Qt::SortOrder)));
und bauen den Slot ein:

Code: Alles auswählen

void Tabelle::sortIndicatorChanged(int logicalIndex, Qt::SortOrder order)
{
    table->sortItems(logicalIndex, order);
}
Im Slot pushButtonClicked() kommt noch an den Anfang

Code: Alles auswählen

table->setSortingEnabled(false);
und ans Ende

Code: Alles auswählen

table->setSortingEnabled(true);
Und wenn wir nichts vergessen haben können wir jetzt mit einem Klick auf den Header einer Spalte
das ganze in die eine oder die andere Richtung sortieren.

Ich kann dir aber nicht alles lösen!
Jannilein
Beiträge: 19
Registriert: 13. Juni 2014 13:38

Re: QTableWidget per Buttonclick mit Inhalt aus QLineEdit 's

Beitrag von Jannilein »

Oh Oha dankeschön, nein sollst du auch garnicht, ich hatte ehr mit einem Tipp oder ähnliches gerechnet.
OKey , dachte ich muss den algorytmus zum sortieren von a-z selbst schreiben ..
Habe damit alles mögliche ausprobiert und hatte nicht funktioniert.
Ich bin dir dankbar ich habe es richtig gut verstanden, villeicht solltest du mal ein buch schreiben ? ^^
Ich habe in den letzten Tagen soviel gegooglt wie noch nie, aber ich finde es ohne wirkliche erklärungen einfach unverständlich.
Die QT seite zeigt gut was es gibt, aber ich finde die erklärungen alles andere als gut, was aber wohl daran liegt, das ich noch "unerfahren" bin.
Danke danke danke ! :D
Darf ich fragen wie lange du schon Programmierst ? Und aus Hobby oder als Job ? :)
archer
Beiträge: 306
Registriert: 2. Februar 2006 09:56

Re: QTableWidget per Buttonclick mit Inhalt aus QLineEdit 's

Beitrag von archer »

Ja darft du, ich programmiere beruflich sein über 10 Jahren.
Antworten