2012-05-28 6 views
7

Próbuję dynamicznie tworzyć układy w mojej klasie MainWindow. Mam cztery ramki, które są układane z obiektem układu siatki. Każda ramka zawiera niestandardowy widget ClockWidget. Chcę, aby obiekty ClockWidget odpowiednio zmieniły rozmiar podczas zmiany rozmiaru głównego okna, więc muszę dodać je do układu. Jednak muszę to zrobić w czasie wykonywania, ponieważ sam obiekt jest tworzony w czasie wykonywania. Próbowałem wykonać to programowo, ale kod komentarza poniżej, który próbuje utworzyć nowy układ, powoduje awarię programu. Jaka jest procedura robienia tego poprawnie?Qt Tworzenie układów i dynamiczne dodawanie widgetów do układów

plik nagłówka:

#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 

plik realizacja:

#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

Czy istnieją jakieś użyteczne informacje w katastrofie? Czy próbowałeś ustawić nadrzędnego dla każdego układu podczas init: 'new QVBoxLayout (frame_1)', zamiast wywołań 'setLayout()'? – jdi

Odpowiedz

6

Twoja procedura jest poprawna. Istnieje kilka literówek, na przykład, ustawiasz układ dwukrotnie dla frame3. To może być twój problem. Awarie nie zawsze są powtarzalne. Nie sądzę, żebyś miał inne problemy. Poniżej znajduje się samodzielny przykład. Zachowuje także wszystkie instancje po wartości, unikając przedwczesnej pesymizacji dodatkowego dereferencji za pomocą wskaźnika.

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

I plik projektu 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

Pismo najprawdopodobniej dotyczyło problemów. Próbowałem rekompilacji i teraz zachowuje się zgodnie z oczekiwaniami. – dtg