2016-06-30 38 views
2

我正在构建一个多窗口应用程序,到目前为止使用8个按钮创建并显示MainWidget。我的下一步是让每个按钮都打开一个新的窗口,这个窗口是QWidget的子窗口。我在QVectors中保留了所有按钮和新窗口(应该在单击按钮时打开)。它全部编译时没有警告或错误,但是,当我单击按钮时,相应的QWidget窗口不显示。Qt - 子窗口小部件没有显示

mainwidget.h

#ifndef MAINWIDGET_H 
#define MAINWIDGET_H 

#include <QWidget> 
#include <QPushButton> 
#include <QGridLayout> 
#include <QSignalMapper> 

#include "examwindow.h" 


namespace Ui { class MainWidget; } 

class MainWidget : public QWidget { 
    Q_OBJECT 

public: 
    explicit MainWidget(QWidget *parent = 0); 
    ~MainWidget(); 

private: 
    Ui::MainWidget *ui; 

    int nExams; 
    QVector<QString> titles; 
    QVector<QPushButton*> examButtons; 
    QGridLayout* mainWidgetLayout; 
    QVector<ExamWindow*> examWindows; 

public slots: 
    void clickedExamW(); 
}; 

#endif // MAINWIDGET_H 

mainwidget.cpp

#include "mainwidget.h" 
#include "ui_mainwidget.h" 
#include <QDesktopWidget> 
#include <iostream> 
MainWidget::MainWidget(QWidget *parent) : QWidget(parent), ui(new Ui::MainWidget) 
{ 
    ui->setupUi(this); 

    /** 
    * @brief Resize the main window size in proportion to the desktop size 
    */ 
    double ratio = 0.7; 
    resize(QDesktopWidget().availableGeometry(this).size() * ratio); 

    /** 
    * @brief Set the main window position in the desktop center 
    */ 
    QDesktopWidget dw; 
    int width = this->frameGeometry().width(); 
    int height = this->frameGeometry().height(); 
    int screenWidth = dw.screen() -> width(); 
    int screenHeight = dw.screen() -> height(); 
    this->setGeometry((screenWidth/2) - (width/2), (screenHeight/2) - (height/2), width, height); 

    /** 
    * Set the button titles 
    */ 
    titles.push_back("FCE - 2008"); 
    titles.push_back("CAE - 2008"); 
    titles.push_back("CPE - 2008"); 
    titles.push_back("ЕГЭ"); 
    titles.push_back("FCE - 2015"); 
    titles.push_back("CAE - 2015"); 
    titles.push_back("CPE - 2015"); 
    titles.push_back("User's Format"); 

    /** 
    * Create buttons 
    */ 
    nExams = 8;   // Number of exams 

    examButtons.resize(nExams); 
    for(int i = 0; i < nExams; i++) { 
     examButtons[i] = new QPushButton(titles[i]); 
     examButtons[i]->setMinimumSize(QSize(150, 150)); 
     examButtons[i]->setMaximumSize(QSize(500, 500)); 
     examButtons[i]->setObjectName(titles[i]); 
     connect(examButtons[i], SIGNAL(clicked()), this, SLOT(clickedExamW())); 
    } 

    /** 
    * Add exam buttons to the main widget layout 
    */ 
    mainWidgetLayout = new QGridLayout(this); 
    for(int i = 0; i < nExams; i++) 
     if (i < nExams/2) 
      mainWidgetLayout -> addWidget(examButtons[i], i, 0); 
     else 
      mainWidgetLayout -> addWidget(examButtons[i], i - nExams/2, 1); 

    /** 
    * Create exam windows 
    */ 
    examWindows.resize(nExams); 
    for(int i = 0; i < nExams; i++) { 
     examWindows[i] = new ExamWindow(this); 
     examWindows[i]->setWindowTitle(titles[i]); 
    } 



} 

void MainWidget::clickedExamW() { 

    QObject *senderObj = sender(); 
    QString senderObjName = senderObj->objectName(); 
    for(int i = 0; i < nExams; i++) 
     if (senderObjName == titles[i]) { 
      this->setWindowTitle(titles[i]); // WORKS - it changes the title 
      examWindows[i]->show();   // DOES NOT WORK - no win shown 
     } 
} 


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

examwindow.h

#ifndef EXAMWINDOW_H 
#define EXAMWINDOW_H 

#include <QWidget> 

class ExamWindow : public QWidget 
{ 
    Q_OBJECT 
public: 
    explicit ExamWindow(QWidget *parent = 0); 

signals: 

public slots: 

}; 

#endif // EXAMWINDOW_H 

examwindow.cpp

#include "examwindow.h" 

ExamWindow::ExamWindow(QWidget *parent) : QWidget(parent) 
{ 

} 
+1

您想将ExamWindow作为单独的窗口还是作为mainWindow的子部件?我认为你的窗户有错误的位置,你没有看到它。你可以检查isVisible。 – Unick

+0

我希望ExamWindow成为MainWindow的子项而不处理内存管理。从视觉上来说,它应该是一个在MainWindow上方打开的窗口。 UPD:我让我的ExamWindow QDialogs和它的工作。我想知道QDialog和QWidget在这方面有什么不同。 – alekscooper

+1

[''QDialog'是一个顶级窗口](http://doc.qt.io/qt-5/qdialog.html#details)。虽然['QWidget'可以是顶级窗口](http://doc.qt.io/qt-5/qwidget.html#top-level-and-child-widgets),但它不是如果它有父母的一套。 – thuga

回答

3

方式,你如何创建小部件是好的(examWindows[i] = new ExamWindow(this);)。但是:

ExamWindow::ExamWindow(QWidget *parent) 
    : QWidget(parent, Qt::Window) 
{} 

你需要,你需要一个“窗口”,窗口小部件直接specify a flag

或者,如果您不想设置父窗口小部件,您可以设置Qt::WA_DeleteOnClose属性来自动释放内存。请注意,在这种情况下,您的examWindows向量中将有一个无效指针。如果您使用下一个声明,可能会解决:QVector<QPointer<ExamWindow>> examWindows;

0

答案:原来,问题是在这条线:

examWindows[i] = new ExamWindow(this); 

如果我删除“这个”,使我的窗户父母双亡的孤儿,它按预期工作。我很困惑,为什么我想我现在必须手动删除它们。

+3

您不需要手动删除小部件。检查我的答案。 –

相关问题