2012-05-28 2 views
7

내 MainWindow 클래스에서 동적으로 레이아웃을 만들려고합니다. 나는 격자 레이아웃 객체로 놓인 네 개의 프레임을 가지고있다. 각 프레임에는 사용자 정의 ClockWidget이 있습니다. 메인 윈도우의 크기를 조정할 때 ClockWidget 객체의 크기를 적절히 조절하여 레이아웃에 추가해야합니다. 그러나 런타임에 객체 자체가 생성되므로 런타임에이 작업을 수행해야합니다. 이 프로그래밍 방식으로 달성하려하지만 아래 주석 된 코드를 새 레이아웃을 만들려고하면 프로그램이 충돌합니다. 이 작업을 올바르게 수행하기위한 절차는 무엇입니까?Qt 레이아웃을 만들고 레이아웃에 위젯을 동적으로 추가합니다.

헤더 파일 :

#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 

구현 파일 :

#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

크래시에 유용한 정보가 있습니까? 'setLayout()'대신 init :'new QVBoxLayout (frame_1)'에서 각 레이아웃의 부모를 설정해 보았습니까? – jdi

답변

6

귀하의 절차는 올바른 것입니다. 몇 가지 오타가 있습니다. 예를 들어 frame3에 대해 레이아웃을 두 번 설정하는 경우입니다. 그것은 당신의 문제 일 수 있습니다. 충돌이 항상 재현 가능하지는 않습니다. 다른 문제가 있다고 생각하지 않습니다. 다음은 자체 포함 된 예제입니다. 또한 모든 인스턴스를 값으로 유지하므로 포인터를 통한 추가 역 참조의 조기 페이지 화를 피할 수 있습니다.

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

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

오타가 가장 많이 발생했습니다. 내가 재 컴파일을 시도하고 지금은 원하는대로 동작합니다. – dtg

관련 문제