[gelöst] Widget in MainWindow einbinden

Alles rund um die Programmierung mit Qt
solarix
Beiträge: 1133
Registriert: 7. Juni 2007 19:25

Beitrag von solarix »

"ui" ist ... ein Pointer...

Auf die Member (Variabeln/Methoden) eines Pointers wird nicht mit einem Punkt (".")

Code: Alles auswählen

ui.TabEins
zugegriffen...

Ich bin mir ausserdem nicht sicher, ob es eine Instanz "TabEins" gibt.. IMHO duerfte es da nur einen Member fuer das TabWidget geben, nicht jedoch fuer die Tabs selbst..
AuE
Beiträge: 918
Registriert: 5. August 2008 10:58

Beitrag von AuE »

so..... also.... du weist den tabs nochmal etwas zu..... du musst aber dem TabbedWidgets die Tabs zuweisen. was du gerade machst ist zu versuchen einen Tab einen Tab zuzuweisen, das geht natürlich nicht.

Folgendes:

Mach ein leere QTabedWidget (keine Tabs) lösche also alle raus!
Dann machst du ui.tabWidget->addWidget(...) (tabedwidget ist das ganze ding....kein einzelner tab)

Code: Alles auswählen

 //QTabWidget *ui=new QTabWidget();  nenn das TabWidget net ui!!!!!!
// ausserdem hast doch das Widget schon drin oder?

   ui.TabWidget->addWidget(new TabEins(), "TabEins"); 
   ui.TabWidget>addWidget(new TabDrei(), "BildFehlerKoeffizient"); 
   ui.TabWidget->addWidget(new TabZwei(), "PhysikalischeParameter");
nici
Beiträge: 246
Registriert: 29. Oktober 2008 12:50

Beitrag von nici »

hi,

ähm was meinst du damit ob ich die Widgets schon drin habe??

hab das jetzt mal so gemacht wie du es gezeigt hast.

Code: Alles auswählen

//konstruktor 
MainWindow::MainWindow(QMainWindow *parent) 
		:QMainWindow(parent)
	{
		setupUi(this);

	QTabWidget *tabwidget=new QTabWidget();
	ui.TabWidget->addWidget(new TabEins(), "TabEins");
	ui.TabWidget->addWidget(new TabDrei(), "BildFehlerKoeffizient");
	ui.TabWidget->addWidget(new TabZwei(), "PhysikalischeParameter");
		
};

Fehlermeldunge:

MainWindow.cpp: In constructor 'MainWindow::MainWindow(QMainWindow*)':
MainWindow.cpp:15: error: 'ui' was not declared in this scope
MainWindow.cpp:14: warning: unused variable 'tabwidget'
make: *** [MainWindow.o] Fehler 1

Muss ich irgendwas für das ui includieren??


Und wenn ich es so mache,

Code: Alles auswählen

//konstruktor 
MainWindow::MainWindow(QMainWindow *parent) 
		:QMainWindow(parent)
	{
		setupUi(this);

	QTabWidget *tabwidget=new QTabWidget();
	tabwidget.TabWidget->addWidget(new TabEins(), "TabEins");
	tabwidget.TabWidget->addWidget(new TabDrei(), "BildFehlerKoeffizient");
	tabwidget.TabWidget->addWidget(new TabZwei(), "PhysikalischeParameter");		
};
dann kommt die alte Fehlermeldung:

MainWindow.cpp: In constructor 'MainWindow::MainWindow(QMainWindow*)':
MainWindow.cpp:15: error: request for member 'TabWidget' in 'tabwidget', which is of non-class type 'QTabWidget*'
MainWindow.cpp:16: error: request for member 'TabWidget' in 'tabwidget', which is of non-class type 'QTabWidget*'
MainWindow.cpp:17: error: request for member 'TabWidget' in 'tabwidget', which is of non-class type 'QTabWidget*'
make: *** [MainWindow.o] Fehler 1


lg

nici
Hmm mir fällt nichts ein ^^
AuE
Beiträge: 918
Registriert: 5. August 2008 10:58

Beitrag von AuE »

sag mal hast du net in deinem ui schon ein QTabWidget?
Wieso versuchst du dann nochmals eins hinzuzufügen?

Allerdings wo ich gerade deinen Code und deine Fehler sehe... so lang programmierste noch net oder?
nici
Beiträge: 246
Registriert: 29. Oktober 2008 12:50

Beitrag von nici »

ich versuche doch nicht, noch eines einzufügen. Ich sollte von meinem Betreuer aus, 3 Widgets erstellen, und die dann in die Tabs einfügen.

Ne an dem Programm programmier ich noch nicht so lange und würde ich weiter kommen, hätte ich auch schon viel mehr.

lg

nici
Hmm mir fällt nichts ein ^^
pfid
Beiträge: 535
Registriert: 22. Februar 2008 16:59

Beitrag von pfid »

nici hat geschrieben:hi,

ähm was meinst du damit ob ich die Widgets schon drin habe??

hab das jetzt mal so gemacht wie du es gezeigt hast.

Code: Alles auswählen

//konstruktor 
MainWindow::MainWindow(QMainWindow *parent) 
		:QMainWindow(parent)
	{
		setupUi(this);

	QTabWidget *tabwidget=new QTabWidget();
	ui.TabWidget->addWidget(new TabEins(), "TabEins");
	ui.TabWidget->addWidget(new TabDrei(), "BildFehlerKoeffizient");
	ui.TabWidget->addWidget(new TabZwei(), "PhysikalischeParameter");
		
};

Fehlermeldunge:

MainWindow.cpp: In constructor 'MainWindow::MainWindow(QMainWindow*)':
MainWindow.cpp:15: error: 'ui' was not declared in this scope
MainWindow.cpp:14: warning: unused variable 'tabwidget'
make: *** [MainWindow.o] Fehler 1

Muss ich irgendwas für das ui includieren??


Und wenn ich es so mache,

Code: Alles auswählen

//konstruktor 
MainWindow::MainWindow(QMainWindow *parent) 
		:QMainWindow(parent)
	{
		setupUi(this);

	QTabWidget *tabwidget=new QTabWidget();
	tabwidget.TabWidget->addWidget(new TabEins(), "TabEins");
	tabwidget.TabWidget->addWidget(new TabDrei(), "BildFehlerKoeffizient");
	tabwidget.TabWidget->addWidget(new TabZwei(), "PhysikalischeParameter");		
};
dann kommt die alte Fehlermeldung:

MainWindow.cpp: In constructor 'MainWindow::MainWindow(QMainWindow*)':
MainWindow.cpp:15: error: request for member 'TabWidget' in 'tabwidget', which is of non-class type 'QTabWidget*'
MainWindow.cpp:16: error: request for member 'TabWidget' in 'tabwidget', which is of non-class type 'QTabWidget*'
MainWindow.cpp:17: error: request for member 'TabWidget' in 'tabwidget', which is of non-class type 'QTabWidget*'
make: *** [MainWindow.o] Fehler 1


lg

nici
Wenn ich das auf den letzten Seiten in einem deiner unzähligen Posts richtig gelesen habe, hast du das TabWidget im Designer erstellt.

In dem Code den du nun gepostet hast, erzeugst du per new ein neues TabWidget. Du hättest somit also 2. Abgesehn davon, dass das komplett sinnfrei ist, hast du dem TabWidget im Konstruktor auch keinen Parent mitgegeben. In dieses zweite TabWidget fügst du dann 3 Widgets per addWidget ein.
Gut dass es Fehler schmeisst, denn was sinnvolles würde bei dieser Konstruktion auch nicht rauskommen.

Um dir die Sache nochmals zu vereinfachen, eine kurze Anleitung wie man das Designer File im Code verwendet:

- Mainwindow im Designer gestalten (TabWidget einfügen, im TabWidget einzelne Tabs mit Inhalt füllen - eben per Drag & Drop Sachen aus der Palette ins Fenster ziehen)

- Dabei auf die Namensgebung der Objekte achten. Beispiel: Wenn du in ein leeres Projekt ein TabWidget reinziehst, hat dieses als Objektname (Im Eigenschaften-Fenster des Designers) "tabWidget". Diesen Namen kannst du so lassen, nur musst du genau diesen Namen wissen, um später auf das TabWidget im Code zugreifen zu können

- die richtige .h Datei inkludieren. Beispiel:

Code: Alles auswählen

#include <ui_project.h>
falls du dein Designer-File "project.ui" genannt hast.

- C++ Dateien anlegen, und eine Klasse von QMainWindow UND der UI-Klasse aus dem Designer erben lassen. Beispiel:

Code: Alles auswählen

class ProjectWindow : public QMainWindow, private Ui::ProjectWindow
{
- Im Konstruktor der Klasse rufst du die Methode setupUi auf, und gibts this als Parameter mit. Damit werden die Objekte, die du im Designer angelegt hast, erzeugt.

- Wenn du das Programm jetzt kompilierst, dürfte das Fenster schon fertig sein. Ggfs. musst du in der main-Funktion (oder eben da, wo deine Fenster-Klasse verwendet wird) entsprechend die show()-Methode aufrufen. Beispiel:

Code: Alles auswählen

ProjectWindow window;
window.show();
- Wenn du jetzt auf Elemente des TabWidgets zugreifen willst, geht das ganz einfach.
1) du weißt es ist ein QTabWidget. Also schaust du in der Doku, welche Zugriffsmethoden die Klasse bietet. Da findest du zum Beispiel die methode addWidget(), sowie widget(). Die Doku verrät dir, wozu diese Methoden gut sind, und welche Parameter sie erwarten.
2) die im Designer erzeugten Objekte werden mit new erzeugt, es handelt sich dementsprechend um Zeiger, und du musst per -> darauf zugreifen, NICHT mit .
3) da du dir, wie angewiesen, den Namen des TabWidgets im Designer gemerkt hast, kannst du nun auch problemlos darauf zugreifen. Beispiel:

Code: Alles auswählen

void ProjectWindow:irgendeineMethode()
{
   tabWidget->addWidget(new QLabel(this, "Mein Label"), "Meine Tab-Beschriftung");
}
Damit hast du dein im Designer erstelltes Fenster im Code eingebunden, und im Nachhinein ein weiteres Tab zum TabWidget hinzugefügt.

Und bevor du fragst: Nein, ich habe die Hoffnung immer noch nicht aufgegeben, dass du endlich mal die C++ Grundlagen und die Qt-Doku anschaust.

[edit] Hier noch der Alternative Weg, komplett ohne Designer:

- C++ Dateien erstellen und eine Klasse von QMainWindow erben lassen (beispiel siehe oben)

- im Konstruktor erzeugst du deine Widgets selbst, etwa so:

Code: Alles auswählen

ProjectWindow:ProjectWindow()
{
   QLabel* label = new QLabel("Mein eigenes TabWidget:", this);
   QTabWidget* tabWidget = new QTabWidget(this);

   tabWidget->addWidget(new QLabel("Mein Label", this), "Mein Tab 1");
   tabWidget->addWidget(new QPusButton("Mein Pushbutton", this), "Mein Tab 2");
   tabWidget->addWidget(new QCheckBox("Meine Checkbox", this), "Mein Tab 3");
}
- in der main-Methode (oder wo auch immer das Fenster erzeugt wird) ggfs. die show()-Methode aufrufen (beispiel siehe oben)

- auf das TabWidget kannst du so einfach nun aber nicht in anderen Methoden zugreifen, da die tabWidget Variable eine lokale Variable im Konstruktor ist, auf die du sonst nirgends Zugriff hast. Eine Möglichkeit wäre, die child-Elemente des Fensters abzufragen, einfacher ist es aber, das TabWidget als Klassenvariable zu deklarieren (diese Transferleistung überlasse ich dir)

- Das Fenster hat nun kein Layout, und die Größe/Position wurde auch nicht gesetzt. Dementsprechend wird es aussehen wie Kraut und Rüben. Aber die Größe/Position des Fensters bekommst du selber hin (QMainWindow Doku), und das mit dem Layout auch (Layout Examples/Tutorials)
Zuletzt geändert von pfid am 24. November 2008 09:42, insgesamt 1-mal geändert.
AuE
Beiträge: 918
Registriert: 5. August 2008 10:58

Beitrag von AuE »

rofl

sehr geil und so muss es auch was werden @pfid

aber warum vererbt ihr da andauernd? Wieso muss das Tabwidget vom Tab erben??? Das rafffe ich grade net... fügt er dann automatisch das Widget ins Tab?
Dateianhänge
DUMMY.rar
(232.73 KiB) 188-mal heruntergeladen
nici
Beiträge: 246
Registriert: 29. Oktober 2008 12:50

Beitrag von nici »

hallo,
danke AuE für dein dummy-Projekt, aber bei dir werden ja Tabs per Code dazu gefügt.
Und danke pfid für deine ausführliche Erklärung. Ich bin deinen Anweisungen gefolgt.

MainWindow.cpp

Code: Alles auswählen

#include "MainWindow.h"
#include <ui_MainWindow.h>
#include <QTabWidget>
#include <QPushButton>

//konstruktor 
MainWindow::MainWindow(QMainWindow *parent) 
		:QMainWindow(parent)
	{
		setupUi(this);
};
//destruktor
MainWindow:: ~MainWindow(){
};

void MainWindow::saveFile() {
	
	tabWidget->addWidget(new QPushButton(this, "speichern"),"BFK");	
}
MainWindow.h

Code: Alles auswählen

#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QTabWidget>

#include "ui_MainWindow.h"

class QDoubleValidator;
class MainWindow : public QMainWindow, private Ui::MainWindow 
{
	Q_OBJECT
	
	public:
		MainWindow(QMainWindow *parent=0);
		~MainWindow();
	
	public slots:
			void saveFile();
		
};
#endif
main.cpp

Code: Alles auswählen

#include "MainWindow.h"
#include <QApplication>
#include <QtGui>

int main(int argc, char *argv[])
{
	QApplication app(argc,argv);
	MainWindow tabeins;
	tabeins.show();
	
	return app.exec();
}
Fehlermeldung:
MainWindow.cpp: In member function 'void MainWindow::saveFile()':
MainWindow.cpp:19: error: 'class QTabWidget' has no member named 'addWidget'
MainWindow.cpp:19: error: no matching function for call to 'QPushButton::QPushButton(MainWindow* const, const char [10])'
/usr/include/qt4/QtGui/qpushbutton.h:89: note: candidates are: QPushButton::QPushButton(const QPushButton&)
/usr/include/qt4/QtGui/qpushbutton.h:47: note: QPushButton::QPushButton(const QIcon&, const QString&, QWidget*)
/usr/include/qt4/QtGui/qpushbutton.h:46: note: QPushButton::QPushButton(const QString&, QWidget*)
/usr/include/qt4/QtGui/qpushbutton.h:45: note: QPushButton::QPushButton(QWidget*)
make: *** [MainWindow.o] Fehler 1

Irgendwie hab ich dich nicht ganz verstanden, war (für mich) etwas durcheinander.
Ich habe in die Tabs die in meinem MainWindow sind die einzelnen Elemente eingefügt. In alle drei Tabs.
Hmm mir fällt nichts ein ^^
pfid
Beiträge: 535
Registriert: 22. Februar 2008 16:59

Beitrag von pfid »

Der Konstruktor von QPushButton ist falsch. Zuerst der Text, dann der Parent-Pointer.

[edit] Da du immer noch nicht C++ lernen willst:
MainWindow.cpp:19: error: no matching function for call to 'QPushButton::QPushButton(MainWindow* const, const char [10])'
/usr/include/qt4/QtGui/qpushbutton.h:89: note: candidates are: QPushButton::QPushButton(const QPushButton&)
/usr/include/qt4/QtGui/qpushbutton.h:47: note: QPushButton::QPushButton(const QIcon&, const QString&, QWidget*)
/usr/include/qt4/QtGui/qpushbutton.h:46: note: QPushButton::QPushButton(const QString&, QWidget*)
/usr/include/qt4/QtGui/qpushbutton.h:45: note: QPushButton::QPushButton(QWidget*)
Bedeutet auf deutsch:

- er hat bei der Klasse QPushButton keine Methode gefunden names QPushButton(MainWindow*, const char[10]) (Konstruktor, achte auf die Reihenfolge der Parameter)

- er schlägt dir aber folgende existierende Methoden (Konstruktoren vor):
QPushButton::QPushButton(const QIcon&, const QString&, QWidget*)
QPushButton::QPushButton(const QString&, QWidget*)
QPushButton::QPushButton(QWidget*)
(achte auf die Reihenfolge der Parameter)

Kurz: Du hast im Konstruktor zuerst den Parent-Pointer angegeben und dann den Text, so einen Konstruktor hat QPushButton aber nicht (nur die anderen vorgeschlagenen).
Zuletzt geändert von pfid am 24. November 2008 14:01, insgesamt 1-mal geändert.
nici
Beiträge: 246
Registriert: 29. Oktober 2008 12:50

Beitrag von nici »

danke, stimmt hätte ich auch von alleine drauf kommen können ^^.
Aber trotzdem kommt noch ein Fehler.

MainWindow.cpp: In member function 'void MainWindow::saveFile()':
MainWindow.cpp:18: error: 'class QTabWidget' has no member named 'addWidget'
make: *** [MainWindow.o] Fehler 1

lg

nici
Hmm mir fällt nichts ein ^^
pfid
Beiträge: 535
Registriert: 22. Februar 2008 16:59

Beitrag von pfid »

nici hat geschrieben:danke, stimmt hätte ich auch von alleine drauf kommen können ^^.
Aber trotzdem kommt noch ein Fehler.

MainWindow.cpp: In member function 'void MainWindow::saveFile()':
MainWindow.cpp:18: error: 'class QTabWidget' has no member named 'addWidget'
make: *** [MainWindow.o] Fehler 1

lg

nici
Ja das ist mein Fehler. Die Methode heißt addTab. Siehe auch Doku.

(Hatte ich das nich auf einer der vorigen seiten schonmal verwechselt? :oops: )
nici
Beiträge: 246
Registriert: 29. Oktober 2008 12:50

Beitrag von nici »

hi,

also jetzt hat es geklappt, ich kann auf die Elemente auf dem ersten Tab zugreifen. Mache ich es dann für den zweiten und den dritten Tag auch so.
Habe gerade versucht auf den PushButton auf dem zweiten Tab zuzugreifen, ging aber nicht.

Code: Alles auswählen

#include "MainWindow.h"
#include <ui_MainWindow.h>
#include <QTabWidget>
#include <QPushButton>
#include <QFileDialog>
#include <QDebug>s

//konstruktor 
MainWindow::MainWindow(QMainWindow *parent) 
		:QMainWindow(parent)
	{
		setupUi(this);
		
		connect(savePB, SIGNAL(clicked()),
			this, SLOT(saveFile()));
		connect(loadPB, SIGNAL(clicked()),
			this,SLOT(loadFile()));
		
		
};
//destruktor
MainWindow:: ~MainWindow(){
};

void MainWindow::saveFile() {
	
	tabWidget->addTab(new QPushButton("speichern",this),"TabEins");	
	 QFileDialog *tmp = new QFileDialog; 
        
   QString Dateiendung= "*.png";
   QString fileName = tmp->getSaveFileName (this, "Speichern", "unbekannt" ,"*.png;; *.jgp;; *.jpeg;; *.bmp;; *.tiff;; *.xbm;; 							*.xpm", &Dateiendung);
   //falls vom Benutzer keine Dateiendung angegeben wird:    
   qWarning() << "TEST" << fileName;

   if (fileName.section('.', -1)!=Dateiendung.section('.',-1))
   {  //Dateiendung an den Namen hängen:
      fileName.append(Dateiendung.section('*',-1));
   }
   imageLabel->pixmap()->save(fileName);
}

// dieser Button ist auf dem zweiten Tab
void MainWindow::loadFile(){
		tabWidget->addTab(new QPushButton("laden",this),"BKF");	

	
QString fileName = QFileDialog::getOpenFileName(this, "Open File", "/home",("Images(*.png *.gif *.jgp *.jpeg *.bmp *.tiff *.xbm *.xpm)"));
	if(!fileName.isEmpty()){											  
 	QImage file(fileName);
    if(file.isNull()) { qWarning()<<"Fehler beim öffnen der Datei!";
	}
	qWarning() << "ok";
	imageLabel->setPixmap(QPixmap::fromImage(file));
	}	
	
	
}
lg

nici
Hmm mir fällt nichts ein ^^
pfid
Beiträge: 535
Registriert: 22. Februar 2008 16:59

Beitrag von pfid »

Was macht denn die Methode addTab?

Was macht new QPushButton(...)?
nici
Beiträge: 246
Registriert: 29. Oktober 2008 12:50

Beitrag von nici »

addTab fügt ein neues Tab zur Lieste, aber das will ich doch gar nicht, ich hab doch schon mittels designer 3 Tabs drin.
Hmm mir fällt nichts ein ^^
pfid
Beiträge: 535
Registriert: 22. Februar 2008 16:59

Beitrag von pfid »

nici hat geschrieben:aber das will ich doch gar nicht, ich hab doch schon mittels designer 3 Tabs drin.
... also?
Antworten