qt Anfängerprobleme

R

rdg

???
Hi,

ich bin mal wieder dabei mich an qt herranzuwagen, doch ich bekomme es nicht hin.
Ich will ein Stapellayout, in dem ich anstatt eines widgets ein layout ändern kann.

main.cpp
Code:
#include <QApplication>
#include <QtGui>
#include "StapelLayout.h"
#include "Zeiger_normal.h"
#include "ButtonBox.h"

int main(int argc, char *argv[]){

	QApplication app(argc, argv);
	StapelLayout *w;// = new StapelLayout;

	Zeiger_normal *zeigernormal;// = new zeiger_normal;
	ButtonBox *buttonbox;

	//zeigerDialog zd;
	//zd.setAttribute(Qt::WA_QuitOnClose);

	w->addStapel("Zeiger normal",zeigernormal);

	return app.exec();
}

StapelLayout.h
Code:
#ifndef STAPELLAYOUT_H
#define STAPELLAYOUT_H
#include <QLayout>
#include <QListWidget>
#include <QStackedLayout>

class StapelLayout : public QLayout {
	public:
	StapelLayout(QLayout *parentLayout = 0);
	void addStapel(const QString& title, QLayout *lay);
	private:
	QStackedLayout *layoutStack;
	QListWidget *pageListWidget;
};
#endif


StapelLayout.cpp
Code:
#include "StapelLayout.h"

#include <QtGui>
#include <QApplication>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QGridLayout>
#include <iostream>

using namespace std;


StapelLayout::StapelLayout( QLayout *parentLayout) : QLayout (parentLayout)  {
	QVBoxLayout *vlay  = new QVBoxLayout;
	QHBoxLayout *hlay  = new QHBoxLayout;
	pageListWidget = new QListWidget;
	layoutStack    = new QStackedLayout;

	vlay->addWidget(layoutStack);
	vlay->addWidget(Buttonbox);

	hlay->addWidget(pageListWidget);
	hlay->addWidget(vlay);

	lay->addWidget(layoutStack);
	// Signal-Slot-Verbindung einrichten
	//connect( pageListWidget, SIGNAL( activated(int ) ),
	//         widgetStack, SLOT( setCurrentIndex( int ) ));
}

void StapelLayout::addStapel(const QString& title, QLayout *lay ) {
   pageListWidget->addItem(title);
   layoutStack->addlayout(lay);
}


Zeiger_normal.h
Code:
#ifndef ZEIGER_NORMAL_H
#define ZEIGER_NORMAL_H
#include <QApplication>
#include <QObject>
#include <QWidget>
#include <QGridLayout>
#include <QLabel>
#include <QPushButton> 


class Zeiger_normal: public QLayout{

	Q_OBJECT 

	public:
	Zeiger_normal();

	QGridLayout* grid_zeiger_normal;	

};
#endif

Zeiger_normal.cpp
Code:
include <Zeiger_normal.h>

Zeiger_normal::Zeiger_normal(){

	QVBoxLayout* mainLayout = new QVBoxLayout(this);
	QGridLayout* grid_zeiger_normal = new QGridLayout;

	QLabel *label[12][2];

	int i =0;
	int j =0;
	label[i] [j] = new QLabel(tr("<h3><u> Zeiger normal: </u></h3>"));
	grid_zeiger_normal->addWidget(label[i][j],i,j);

// 1 0
	i=1;
	j=0;
	label[i][j] = new QLabel(tr("<b> Hat die Adresse |</b>"));
	grid_zeiger_normal->addWidget(label[i][j] ,i,j);
	j++;	
	label[i][j] = new QLabel(tr("<b> Inhalt der Adr. |</b>"));
	grid_zeiger_normal->addWidget(label[i][j] ,i,j);
	j++;
	label[i][j] = new QLabel(tr("<b> Inhalt dieser Adr.</b>"));
	grid_zeiger_normal->addWidget(label[i][j] ,i,j);
// 2 0
	int *ptr;

	i=2;
	j=0;
	label[i][j] = new QLabel(tr("<font color=gray ><b>*ptr;</b></font>"));
	label[i][j]->setFrameStyle(QFrame::Box | QFrame::Plain);
	grid_zeiger_normal->addWidget(label[i][j] ,i,j);
// 3 0
	i=3;
	j=0;
			
	label[i][j] = new QLabel(QString("<font color=red   ><b>&ptr: %1 </b></font>").arg(int  (&ptr)));
	//label[i][j] = new QLabel(QString(char* &ptr));
	label[i][j]->setFrameStyle(QFrame::Box | QFrame::Plain);
	grid_zeiger_normal->addWidget(label[i][j] ,i,j);
	j++;
	label[i][j] = new QLabel(QString("<font color=green ><b>ptr: %1 </b></font>").arg(int (ptr)));
	label[i][j]->setFrameStyle(QFrame::Box | QFrame::Plain);
	grid_zeiger_normal->addWidget(label[i][j] ,i,j);
	j++;
	label[i][j] = new QLabel(QString("<font color=brown ><b>*ptr: %1 </b></font>").arg(int (*ptr)));
	label[i][j]->setFrameStyle(QFrame::Box | QFrame::Plain);
	grid_zeiger_normal->addWidget(label[i][j] ,i,j);
// 4 0
	int t=5;

	i=4;
	j=0;
	label[i][j] = new QLabel(tr("<font color=gray ><b>int t=5;</b></font>"));
	label[i][j]->setFrameStyle(QFrame::Box | QFrame::Plain);
	grid_zeiger_normal->addWidget(label[i][j] ,i,j);
//5 0
	i=5;
	j=0;

	label[i][j] = new QLabel(QString("<font color=red ><b>&ptr: %1 </b></font>").arg(int (&t)));
	label[i][j]->setFrameStyle(QFrame::Box | QFrame::Plain);
	grid_zeiger_normal->addWidget(label[i][j] ,i,j);
	j++;
	label[i][j] = new QLabel(QString("<font color=green ><b>ptr: %1 </b></font>").arg(int (t)));
	label[i][j]->setFrameStyle(QFrame::Box | QFrame::Plain);
	grid_zeiger_normal->addWidget(label[i][j] ,i,j);
	j++;

	mainLayout->addLayout(grid_zeiger_normal);
	mainLayout->addStretch();


	QHBoxLayout* buttonLayout = new QHBoxLayout(this);
	QPushButton* exitButton = new QPushButton(tr("Beenden"));
	buttonLayout->addStretch();
	buttonLayout->addWidget(exitButton);
	buttonLayout->addStretch();
	mainLayout->addLayout(buttonLayout);
}

ButtonBox.h
Code:
#ifndef BUTTONBOX_H
#define BUTTONBOX_H
#include <QApplication>
#include <QObject>
#include <QWidget>
#include <QGridLayout>
#include <QLabel>
#include <QPushButton> 
#include <QHBoxLayout> 
#include "StapelLayout.h"


class ButtonBox: public StapelLayout{

	Q_OBJECT 

	public:
	ButtonBox();

};
#endif


ButtonBox.h
Code:
#include "ButtonBox.h"

ButtonBox::ButtonBox(){
	QHBoxLayout* buttonLayout = new QHBoxLayout;
	QPushButton* exitButton = new QPushButton(tr("Beenden"));
	buttonLayout->addStretch();
	buttonLayout->addWidget(exitButton);
}

Wie der erfahrene Programmierer schnell sieht bin ich damit überfordert.
Zum einen macht die Funktion addStapel sehr zuschaffen zum anderen auch vlay->addWidget(Buttonbox); <-Eltern ist schon QLayout . Insgesammt kann man sagen, habe ich mich ziemlich verlaufen und es hakt am ganzen Code.
Ich habe mich schon genug mit den Grundlagen befasst, doch es fällt mir sehr schwer diese auch in der Praxis anzuwenden, ich habe halt keine praktische Erfahrung, deshalb bitte ich Euch um hilfe.
Wenn jemand sich die Mühe macht mir dabei zu helfen, wäre ich ihm sehr dankbar!
vielen dank
rdg
 
Zuletzt bearbeitet:
Ich will ein Stapellayout, in dem ich anstatt eines widgets ein layout ändern kann.
Ganz verstanden habe ich das nicht, denn ich hätte gesagt, daß einem Layout ein oder mehrere Widgets hinzugefügt werden können. Zudem habe ich mit dem QStackedLayout bisher noch nicht gearbeitet, vermute aber, daß es sich dabei um den Nachfolger des QWidgetStack handelt.

Mein Vorschlag: Ich empfehle Dir, Dich anfangs zuerst einmal dem Qt Designer vertraut zu machen. Der Designer erspart einem allein schon beim Positionieren von Widgets innerhalb eines Fensters eine Menge Fummelei und hilft damit enorm Zeit zu sparen.

Zudem kann man aus dem erzeugten Code eine Menge lernen. Ich selber erstelle Fenster zuerst damit, und wenn es dann wirklich einmal nötig sein sollte, nehme ich den Code als Vorlage, um diesen zu erweitern oder zu vereinfachen.

Ich hoffe, daß die schnellgeschriebenen Beispiele gut genug zu Deinem Problem passen und etwas weiterhelfen:

main.cpp
Code:
#include <qapplication.h>
#include "mainform.h"

int main( int argc, char ** argv )
{
    QApplication a( argc, argv );
    MainForm w;
    w.show();
    a.connect( &a, SIGNAL( lastWindowClosed() ), &a, SLOT( quit() ) );
    return a.exec();
}

mainform.h
Code:
#ifndef MAINFORM_H
#define MAINFORM_H

#include <qdialog.h>

class QPushButton;
class QWidgetStack;
class QWidget;
class QLabel;

class MainForm : public QDialog
{
    Q_OBJECT

public:
    MainForm( QWidget* parent=0, const char* name=0, bool modal=FALSE,
              WFlags fl = 0 );
    ~MainForm();

    QPushButton* pbRwd;
    QPushButton* pbFwd;
    QPushButton* pbClose;
    QWidgetStack* widgetStack;
    QWidget* WStackPage_1;
    QLabel* textLabel1;
    QWidget* WStackPage_2;
    QLabel* textLabel2;
    QWidget* WStackPage_3;
    QLabel* textLabel3;

private:
    int m_currentWidget;
    int m_maxWidgetPage;

public slots:
    virtual void onForward();
    virtual void onRewind();

protected slots:
    virtual void languageChange();
};

#endif // MAINFORM_H

mainform.cpp
Code:
#include <qlabel.h>
#include <qpushbutton.h>
#include <qwidget.h>
#include <qwidgetstack.h>
#include "mainform.h"

MainForm::MainForm( QWidget* parent, const char* name, bool modal, WFlags fl )
    : QDialog( parent, name, modal, fl )
{
    m_currentWidget = 0;
    m_maxWidgetPage = 0;

    if ( !name )
	setName( "MainForm" );

    pbRwd = new QPushButton( this, "pbRwd" );
    pbRwd->setGeometry( QRect( 400, 60, 101, 23 ) );

    pbFwd = new QPushButton( this, "pbFwd" );
    pbFwd->setGeometry( QRect( 400, 20, 101, 23 ) );

    pbClose = new QPushButton( this, "pbClose" );
    pbClose->setGeometry( QRect( 400, 220, 101, 23 ) );
    pbClose->setDefault( TRUE );

    widgetStack = new QWidgetStack( this, "widgetStack" );
    widgetStack->setGeometry( QRect( 20, 10, 340, 240 ) );

    WStackPage_1 = new QWidget( widgetStack, "WStackPage_1" );
    m_maxWidgetPage++;

    textLabel1 = new QLabel( WStackPage_1, "textLabel1" );
    textLabel1->setGeometry( QRect( 110, 90, 110, 30 ) );
    widgetStack->addWidget( WStackPage_1, 0 );

    WStackPage_2 = new QWidget( widgetStack, "WStackPage_2" );
    m_maxWidgetPage++;

    textLabel2 = new QLabel( WStackPage_2, "textLabel2" );
    textLabel2->setGeometry( QRect( 110, 90, 110, 30 ) );
    widgetStack->addWidget( WStackPage_2, 1 );

    WStackPage_3 = new QWidget( widgetStack, "WStackPage_3" );
    m_maxWidgetPage++;

    textLabel3 = new QLabel( WStackPage_3, "textLabel3" );
    textLabel3->setGeometry( QRect( 110, 90, 110, 30 ) );
    widgetStack->addWidget( WStackPage_3, 2 );
    languageChange();
    resize( QSize(541, 282).expandedTo(minimumSizeHint()) );
    clearWState( WState_Polished );

    // signals and slots connections
    connect( pbClose, SIGNAL( clicked() ), this, SLOT( close() ) );
    connect( pbFwd, SIGNAL( clicked() ), this, SLOT( onForward() ) );
    connect( pbRwd, SIGNAL( clicked() ), this, SLOT( onRewind() ) );
}

MainForm::~MainForm()
{
    // no need to delete child widgets, Qt does it all for us
}

void MainForm::onForward()
{
    if (++m_currentWidget >= m_maxWidgetPage)
        m_currentWidget = m_maxWidgetPage-1;
    widgetStack->raiseWidget(m_currentWidget);
}

void MainForm::onRewind()
{
    if (--m_currentWidget < 0)
        m_currentWidget = 0;
    widgetStack->raiseWidget(m_currentWidget);
}

void MainForm::languageChange()
{
    setCaption( tr( "WidgetStack-Demo" ) );
    pbRwd->setText( trUtf8( "\x26\x5a\x75\x72\xc3\xbc\x63\x6b" ) );
    pbRwd->setAccel( QKeySequence( tr( "Alt+Z" ) ) );
    pbFwd->setText( tr( "&Vor" ) );
    pbFwd->setAccel( QKeySequence( tr( "Alt+V" ) ) );
    pbClose->setText( tr( "&Beenden" ) );
    pbClose->setAccel( QKeySequence( tr( "Alt+B" ) ) );
    textLabel1->setText( tr( "Das ist Label 1" ) );
    textLabel2->setText( tr( "Das ist Label 2" ) );
    textLabel3->setText( tr( "Das ist Label 3" ) );
}

Du hattest übrigens Deine Label immer nach dem gleichen Schema in einem 2-D-Array angelegt; falls Du so vorgehst, würde sich der Einsatz einer Funktion vielleicht besser anbieten.

Aus meiner Praxiserfahrung gehe ich aber davon aus, daß man die Größe und Position von Labels häufig individuell anpassen muß und daß es daher in vielen Fällen kompliziert wäre, dafür passende Funktionen zu schreiben.
 
Hi,

erstmal vielen dank für Deine Hilfe, ich weiß deine Bemühung für mich zu würdigen.
An für sich habe ich das System mit den 2 Buttons für weiter und zurück auch verstanden, nur

- wozu benötige ich die Werte im Konstruktor?
MainForm( QWidget* parent=0, const char* name=0, bool modal=FALSE, WFlags fl = 0 );

- worauf bezieht sich this genau und warum muss ich es mit angeben?
z.B.: widgetStack = new QWidgetStack( this, "widgetStack" ); w?<-warum?

schweint qt3 zu sein, oder?
 
Zuletzt bearbeitet:
- wozu benötige ich die Werte im Konstruktor?
MainForm( QWidget* parent=0, const char* name=0, bool modal=FALSE, WFlags fl = 0 );
Diese Werte werden angenommen, um sie dem Konstruktor von QDialog weiterzugegeben. Die Bedeutung der Parameter wird hier beschrieben. Auf parent und name gehe ich später noch ein.

- worauf bezieht sich this genau und warum muss ich es mit angeben?
z.B.: widgetStack = new QWidgetStack( this, "widgetStack" ); w?<-warum?
Du bist wohl C-Programmierer? :) Der "this"-Zeiger zeigt auf das eigene Objekt, also in dem Fall auf MainForm.

Der Konstruktor des Widget Stack erwartet wie schon MainForm zuvor und im übrigen alle QObjects parent und name als Parameter. Der WidgetStack und die PushButtons liegen direkt in MainForm und bekommen daher über den this-Zeiger MainForm als Elternobjekt zugeordnet. Die WidgetStackPages liegen im WidgetStack und bekommen daher über den "widgetStack"-Zeiger diesen als Elternobjekt; die Label liegen in den ihren jeweiligen WidgetStackPages und bekommen daher diese als Elternobjekte.

Wozu das ganze? Wird ein Objekt gelöscht, z.B. WidgetStackPage_3, kann Qt anhand des Objektbaums erkennen, daß Label_3 ein darin befindliches Objekt ist und daher auch gelöscht werden muß. Wollen wir also ein Fenster löschen, kümmert sich Qt um alle darin enthaltenen Objekte und erkennt am Objektbaum, was in welcher Reihenfolge gelöscht werden muß.

Da MainForm ein "top-level widget" ist, hat es den NULL-Zeiger als Zeiger auf sein Elternobjekt übergeben bekommen.

schweint qt3 zu sein, oder?

Ja! Ich vermute das an die Stelle des QWidgetStack jetzt QStackedLayout getreten ist. Versuche mal wie hier vorzugehen:
  1. Erst die QLabels (sind ja auch nur Widgets) erzeugen,
  2. dann QStackedLayout,
  3. dem Ding mit "addWidget" die Labels hinzufügen,
  4. zum Schluß dem MainForm mit "setLayout" das QStackedLayout-Objekt als Layout verpassen.

Vermutlich ist aus dem alten "raiseWidget" jetzt "setCurrentIndex" geworden.
 
Jo,

habe es durch #include <QStackedWidget> insg. ersetzt. Hier und da meckert er auch noch da es in qt4 einige Funktionen nicht mehr gibt.
Doch das ist eigentlich nicht so wichtig, wichtig ist eher, das ich den generellen Umgang mit Klassen von qt besser verstehe und dabei hat mir z.B. deine Erklärung des Sinnes vom Objektbaum z.B. sehr geholfen, vorher wusste ich nicht was und wozu ich dieses überhaupt benötige.
Konstruktor, this, ... werden dadurch klar.
Eine kleine Frage hätte ich aber noch, wozu benötige ich flags?
 
Die WidgetFlags werden hier beschrieben. Man kann Aussehen und Verhalten des Widgets kontrollieren, z.B. die Dinger in der oberen Ecke zum Minimieren, Schließen u.v.m. anzeigen oder verstecken lassen. Der Konstruktor oder auch setWFlags können sie setzen und mit clearWFlags werden sie wieder gelöscht.

Häufig - und auch hier - werden solche Dinge über Bits realisiert. Das Beispiel zeigt, wie man die Flags mit dem Bitweise-Oder-Operator "|" miteinander verknüpfen kann.
 

Ähnliche Themen

GB-errinerung in QT hat Speicherzugrifsfehler

Rollei Mini Wifi Camcorder

Samba 4 Gast Zugang unter Ubuntu funktioniert nicht

Displayport + externer Monitor zeigt bei startx nichts erst bei DVI

iptables weiterleitung port vom internen Netzwerk zum internet Port

Zurück
Oben