2012-05-28 18 views
7

Estoy intentando crear diseños dinámicamente en mi clase MainWindow. Tengo cuatro marcos que se colocan con un objeto de disposición de cuadrícula. Cada cuadro contiene un ClockWidget personalizado. Quiero que los objetos ClockWidget cambien de tamaño según corresponda cuando cambie el tamaño de la ventana principal, por lo que debo agregarlos a un diseño. Sin embargo, tengo que hacer esto en tiempo de ejecución, ya que el objeto en sí se crea en tiempo de ejecución. Traté de lograr esto programáticamente, pero el código comentado a continuación que intenta crear un nuevo diseño hace que el programa falle. ¿Cuál es el procedimiento para hacer esto correctamente?Qt Crear diseños y agregar widgets a diseños dinámicamente

Archivo de cabecera:

#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 

archivo de implementación:

#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

¿Hay alguna información útil en el bloqueo? ¿Has intentado configurar el padre de cada diseño durante el inicio: 'new QVBoxLayout (frame_1)', en lugar de las llamadas 'setLayout()'? – jdi

Respuesta

6

Su procedimiento es correcto. Hay algunos errores ortográficos, por ejemplo, está configurando el diseño dos veces para frame3. Ese puede ser tu problema. Los bloqueos no siempre son reproducibles. No creo que tengas otros problemas que eso. A continuación se muestra un ejemplo independiente. También mantiene todas las instancias por valor, evitando la pesimismo prematura de una desreferencia adicional a través de un puntero.

// 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(); 
} 

Y el archivo del proyecto 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

El error tipográfico era probablemente el problema. Intenté volver a compilar y ahora se comporta como se desea. – dtg