2012-05-28 14 views
7

Sto cercando di creare layout nella mia classe MainWindow in modo dinamico. Ho quattro frame che sono disposti con un oggetto di layout di griglia. Ogni frame contiene un ClockWidget personalizzato. Voglio che gli oggetti ClockWidget si ridimensionino di conseguenza quando ridimensiono la finestra principale, quindi ho bisogno di aggiungerli a un layout. Tuttavia, ho bisogno di farlo in fase di esecuzione, poiché l'oggetto stesso viene creato in fase di runtime. Ho provato a farlo a livello di programmazione, ma il codice commentato di seguito che tenta di creare un nuovo layout causa il crash del programma. Qual è la procedura per farlo correttamente?Qt Creazione di layout e aggiunta di widget ai layout in modo dinamico

file di intestazione:

#ifndef MAINWINDOW_H 
#define MAINWINDOW_H 

#include <QMainWindow> 

#include "ClockView.h" 

namespace Ui{ 
    class MainWindow; 
} 

class QLayout; 

class MainWindow : public QMainWindow 
{ 
    Q_OBJECT 

public: 

    explicit MainWindow(QWidget *parent = 0); 

    ~MainWindow(); 

    void populateViewGrid(); 

private: 

    Ui::MainWindow *ui; 

    ClockView *clockView_1; 
    ClockView *clockView_2; 
    ClockView *clockView_3; 
    ClockView *clockView_4; 

    QLayout *layout_1; 
    QLayout *layout_2; 
    QLayout *layout_3; 
    QLayout *layout_4; 
}; 

#endif // MAINWINDOW_H 

file di implementazione:

#include <QVBoxLayout> 

#include "MainWindow.h" 
#include "ui_MainWindow.h" 

MainWindow::MainWindow(QWidget *parent) : 
    QMainWindow(parent), 
    ui(new Ui::MainWindow) 
{ 
    ui->setupUi(this); 
    populateViewGrid(); 
} 

MainWindow::~MainWindow() 
{ 
    delete ui; 
} 

void MainWindow::populateViewGrid() 
{ 
    clockView_1 = new ClockView(ui->frame_1); 
    clockView_2 = new ClockView(ui->frame_2); 
    clockView_3 = new ClockView(ui->frame_3); 
    clockView_4 = new ClockView(ui->frame_4); 

    /* 
    layout_1 = new QVBoxLayout; 
    layout_2 = new QVBoxLayout; 
    layout_3 = new QVBoxLayout; 
    layout_4 = new QVBoxLayout; 

    layout1->addWidget(clockView_1); 
    layout2->addWidget(clockView_2); 
    layout3->addWidget(clockView_3); 
    layout4->addWidget(clockView_4); 

    ui->frame_1->setLayout(layout_1); 
    ui->frame_2->setLayout(layout_2); 
    ui->frame_3->setLayout(layout_3); 
    ui->frame_3->setLayout(layout_4); 
    */ 
} 
+0

C'è qualche informazione utile nel crash? Hai provato a impostare il genitore di ogni layout durante init: 'new QVBoxLayout (frame_1)', invece delle chiamate 'setLayout()'? – jdi

risposta

6

La procedura è corretta. Ci sono alcuni refusi, ad esempio, stai impostando il layout due volte per frame3. Questo potrebbe essere il tuo problema. Gli arresti non sono sempre riproducibili. Non penso che tu abbia altri problemi oltre a quello. Di seguito è riportato un esempio autonomo. Mantiene anche tutte le istanze in base al valore, evitando la prematura pessimizzazione di un ulteriore dereferimento tramite un puntatore.

// https://github.com/KubaO/stackoverflown/tree/master/questions/dynamic-widget-10790454 
#include <cmath> 
#include <QtGui> 
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0) 
#include <QtWidgets> 
#endif 
#include <array> 

// Interface 

class ClockView : public QLabel 
{ 
public: 
    explicit ClockView(QWidget* parent = nullptr) : QLabel(parent) 
    { 
     static int ctr = 0; 
     setText(QString::number(ctr++)); 
    } 
}; 

class MainWindow : public QMainWindow 
{ 
public: 
    explicit MainWindow(QWidget *parent = nullptr); 
    void populateViewGrid(); 

private: 
    static constexpr int N = 10; 

    QWidget central{this}; 
    QGridLayout centralLayout{&central}; 
    std::array<QFrame, N> frames; 

    std::array<ClockView, N> clockViews; 
    std::array<QVBoxLayout, N> layouts; 
}; 

// Implementation 

MainWindow::MainWindow(QWidget *parent) : 
    QMainWindow(parent) 
{ 
    setCentralWidget(&central); 

    const int n = ceil(sqrt(N)); 
    for (int i = 0; i < N; ++ i) { 
     frames[i].setFrameShape(QFrame::StyledPanel); 
     centralLayout.addWidget(&frames[i], i/n, i%n, 1, 1); 
    } 

    populateViewGrid(); 
} 

void MainWindow::populateViewGrid() 
{ 
    for (int i = 0; i < N; ++ i) { 
     layouts[i].addWidget(&clockViews[i]); 
     frames[i].setLayout(&layouts[i]); 
    } 
} 

int main(int argc, char** argv) 
{ 
    QApplication app{argc, argv}; 
    MainWindow w; 
    w.show(); 
    return app.exec(); 
} 

E il file di progetto qmake.

greaterThan(QT_MAJOR_VERSION, 4) { 
    QT = widgets 
    CONFIG += c++11 
} else { 
    QT = gui 
    unix:QMAKE_CXXFLAGS += -std=c++11 
    macx { 
     QMAKE_CXXFLAGS += -stdlib=libc++ 
     QMAKE_MACOSX_DEPLOYMENT_TARGET = 10.7 
    } 
} 
TARGET = dynamic-widget-10790454 
TEMPLATE = app 
SOURCES += main.cpp 
+0

L'errore di battitura era probabilmente il problema. Ho provato a ricompilare e ora si comporta come desiderato. – dtg

Problemi correlati