[QT (4.8.0)] Abgeleitete Widget-Klassen in GUI verschachteln



  • Hi!

    Werde versuchen, mich nachvollziehbar auszudrücken. Mein Problem ist, dass ich eine Anwendung schreibe, welche im GUI Tabs hat. Für den jeweiligen Inhalt der einzelnen Tabs hingegen möchte ich eigene Klassen schreiben und ableiten. Also für jedes Tab eine Klasse, die ich von QWidget ableite. In der Hauptklasse, werden alle diese Klassen (oder besser gesagt die entsprechenden Instanzen) in die Tabs gepackt und das Menü im Fenster erstellt.

    Mein Problem: Ich kann das Layout für die einzelnen Tab-Klassen nicht setzen! Ich fange mit dem ersten Tab an und erstelle eine Klasse IPOutput, für die ich bereits das Layout erstellt usw. habe, jedoch scheitert setLayout intern an einem bekannten Fehler (Attempting to set Layout...). Meine Frage: Was soll ich tun?

    Konstruktor von IPOutput:

    IPOutput::IPOutput(QWidget* parent):
    QWidget      (new QWidget(this)),
    ImageDisplay (new QLabel(this)),
    Lfps         (new QLabel("Frames per second: ", this)),
    sb_fps       (new QSpinBox(this)),
    op_layout    (new QVBoxLayout(this)),
    ou_layout    (new QVBoxLayout(this)),
    main_layout  (new QGridLayout(this)),
    Options      (new QGroupBox("Options for rendering interface", this)),
    Output       (new QGroupBox("Output", this)),
    fps          (20)
    {
        Lfps->setFont(QFont("Arial", 12));
        sb_fps->setFont(QFont("Arial", 12));
    
        sb_fps->setRange(1, 100);
        sb_fps->resize (150, 30);
        sb_fps->setValue   (fps);
    
        main_layout->addLayout(ou_layout, 0, 0);
        main_layout->addLayout(op_layout, 0, 1);
        setLayout(main_layout);// Hier haperts
    
        ImageDisplay->setPixmap(QPixmap("NoImages.png"));
    
        ou_layout->addWidget(ImageDisplay);
    
        op_layout->addWidget(Lfps);
        op_layout->addWidget(sb_fps);
        op_layout->setAlignment(Qt::AlignTop);
    
        Options->setLayout(op_layout);// Hier auch
        Options->setFont(QFont("Arial", 13, QFont::Bold));
    
        Output->setLayout(ou_layout);//Hier auch
        Output->setFont(QFont("Arial", 13, QFont::Bold));
    
        connect(sb_fps, SIGNAL(valueChanged(int)), this, SLOT(adjust_fps(int)));
    }
    

    VD im VR

    😞



  • Meine erste Idee: Ich leite stattdessen von QLayout ab, erstelle eine eigene Layout-Klasse. In der Hauptklasse werde ich dann ein QWidget erstellen und das Layout auf die Instanz dieser Layout-Klasse stellen, und dieses dann im QTabWidget hinzufügen (also das QWidget). Finde ich aber unschön...



  • Ein Layout verwaltet Widgets (oder andere Layouts, aber ein Layout nur mit Layouts bringt wenig, da nirgendwo was angezeigt wird). Ein Widget kapselt eine Resource, die vom darunterliegenden Windowing System erzeugt und mit events gefüttert wird (so ungefähr...). Jedenfalls ist so eine Window-Resource UNIQUE. Du kannst ein Fenster NUR EINMAL anzeigen. Somit geht es nicht, ein Widget in mehrere Layouts gleichzeitig zu packen. Da Layouts (wie oben gesagt) selber Widgets enthalten, muss zwangsläufig verboten werden, ein Layout in mehrere Layouts/widgets packen zu können. Und genau das machst du mit [op,ou]_layout: Als Layout für ein Widget gesetzt, ebenso ins main_layout gestopft.

    Das "setLayout(main_layout)" geht deshalb schief, weil ein QMainWindow was spezielles ist: Das hat bereits ein eigenes Layout (für Menü, ToolBars, DockWidgets usw.): Ein QMainWindow::setLayout() geht IMMER schief! Du willst dein Layout ins centralWidget des MainWindows setzen.



  • Nein! Diese Klasse ist eigentlich von QWidget abgeleitet! Dieses Problem mit QMainWindow ist mir bekannt, in der Hauptklasse löse ich es so wie du gesagt hast. Hab nur was ausprobiert, und bereits "zurück" editiert. Also nochmal: IPOutput ist jetzt ein QWidget, das Problem ändert nichts..



  • Die Klasse sieht jetzt so aus, hab deine Fehler versucht zu beheben, jedoch läufts immer noch schief:

    IPOutput::IPOutput(QWidget* parent):
    QWidget      (parent),
    ImageDisplay (new QLabel(this)),
    Lfps         (new QLabel("Frames per second: ", this)),
    sb_fps       (new QSpinBox(this)),
    op_layout    (new QVBoxLayout(this)),
    ou_layout    (new QVBoxLayout(this)),
    main_layout  (new QGridLayout(this)),
    Options      (new QGroupBox("Options for rendering interface", this)),
    Output       (new QGroupBox("Output", this)),
    fps          (20)
    {
        Lfps->setFont(QFont("Arial", 12));
        sb_fps->setFont(QFont("Arial", 12));
        setLayout(main_layout);
    
        sb_fps->setRange(1, 100);
        sb_fps->resize (150, 30);
        sb_fps->setValue   (fps);
    
        main_layout->addWidget(Output, 0, 0);//Hier werden die beiden Group-Boxen dem main_layout hinzugefügt
        main_layout->addWidget(Options, 0, 1);
    
        ImageDisplay->setPixmap(QPixmap("NoImages.png"));
    
        ou_layout->addWidget(ImageDisplay);
    
        op_layout->addWidget(Lfps);
        op_layout->addWidget(sb_fps);
        op_layout->setAlignment(Qt::AlignTop);
    
        Options->setLayout(op_layout);/// << Hier wird das Layout der ersten GroupBox gesetzt
        Options->setFont(QFont("Arial", 13, QFont::Bold));
    
        Output->setLayout(ou_layout);/// << Hier wird das Layout der zweiten GroupBox gesetzt
        Output->setFont(QFont("Arial", 13, QFont::Bold));
    
        connect(sb_fps, SIGNAL(valueChanged(int)), this, SLOT(adjust_fps(int)));
    }
    


  • Hab es jetzt hinbekommen!! Minimale Veränderungen und es sieht jetzt so aus:

    IPOutput::IPOutput(QWidget* parent):
    QWidget      (parent),
    ImageDisplay (new QLabel(this)),
    Lfps         (new QLabel("Frames per second: ", this)),
    sb_fps       (new QSpinBox(this)),
    op_layout    (new QVBoxLayout(this)),
    ou_layout    (new QVBoxLayout(this)),
    main_layout  (new QGridLayout(this)),
    Options      (new QGroupBox("Options for rendering interface", this)),
    Output       (new QGroupBox("Output", this)),
    fps          (20)
    {
        Lfps->setFont(QFont("Arial", 12));
        sb_fps->setFont(QFont("Arial", 12));
    
        sb_fps->setRange(1, 100);
        sb_fps->resize (150, 30);
        sb_fps->setValue   (fps);
    
        ImageDisplay->setPixmap(QPixmap("NoImages.png"));
    
        ou_layout->addWidget(ImageDisplay);
    
        op_layout->addWidget(Lfps);
        op_layout->addWidget(sb_fps);
        op_layout->setAlignment(Qt::AlignTop);
    
        Options->setLayout(op_layout);
        Options->setFont(QFont("Arial", 13, QFont::Bold));
    
        Output->setLayout(ou_layout);
        Output->setFont(QFont("Arial", 13, QFont::Bold));
    
        main_layout->addWidget(Output, 0, 0);//Diese Drei Anweisungen stehen jetzt weiter unten, inwiefern macht das einen Unterschied?
        main_layout->addWidget(Options, 0, 1);
        setLayout(main_layout);
    
        connect(sb_fps, SIGNAL(valueChanged(int)), this, SLOT(adjust_fps(int)));
    }
    

Anmelden zum Antworten