2014-10-26 2 views
0

Я хотел бы создать программу, которая показывает вопрос с некоторыми ответами на пользователя. Мое приложение использует 3 формы: Главное меню, Меню входа и Игровая форма, и все наследуются от абстрактного класса Form; Я делаю это, потому что это позволяет использовать заводский метод, который создает новое окно, когда сигнал GoFw испускается фактической формой.Сбой приложения при открытии окна qt

«Цикл», который показывает окна, является следующим: MainMenu -> LoginMenu -> GameForm -> MainMenu ... Проблема в том, когда игра закончена (например, количество оставшихся вопросов равно нулю) GameForm испускает сигнал GoFw, но приложение падает после метода show() (я мог видеть белое окно без кнопок перед сбоем). отладчик показать MessageBox с этой ошибкой:

The inferior stopped because it triggered an exception. 

Stopped in thread 0 by: Exception at 0x723f7b93, code: 0xc0000005: read access 
violation at: 0x0, flags=0x0 (first chance). 

и QtCreator открывает файл с именем: дизассемблер (QHash :: findNode)

Это код заводским способом:

void FormFactory::Init(int formType) 
{ 
    ///if formType == 1 MainMenu is showed 
    if(formType == MAIN_MENU_TYPE) 
    { 
     //inizializza il puntatore 
     actualForm = new MainMenu(); 
    } 
    ///else if is == 2 show ProfileMenu 
    else if(formType == PROFILE_MENU_TYPE) 
    { 
     actualForm = new LoginMenu(); 
    } 
    ///else if == 3 show GameForm 
    else if(formType == GAME_FORM_TYPE) 
    { 
     actualForm = new GameForm(); 
    } 
    ///else if there is no match launch an exception 
    else 
     throw UnexpectedIdEx(); 

    connect(actualForm, SIGNAL(GoFw(int)), this, SLOT(DisplayForm(int))); 
} 

void FormFactory::DisplayForm(int i) 
{ 
    Reset(); 
    Init(i); 
    ///show the form pointed by actualform 
    actualForm->show(); 
} 

void FormFactory::Reset() 
{ 
    disconnect(actualForm, SIGNAL(GoFw(int)), this, SLOT(DisplayForm(int))); 
    ///if actualform is actually pointing to a form, delete it and set actualForm to zero 
    if(actualForm!=0) 
     delete actualForm; 
    actualForm = 0; 
} 

И код MainMenu.cpp является

MainMenu::MainMenu() 
{ 
    setUpGui(); 
} 

void MainMenu::setUpGui() 
{ 
    playButton = new QPushButton(tr("Play")); 
    infoButton = new QPushButton(tr("Info")); 
    quitButton = new QPushButton(tr("Exit")); 

    ///connect the clicked signal to the related slot 
    connect(infoButton, SIGNAL(clicked()), this, SLOT(info())); 
    connect(quitButton, SIGNAL(clicked()), this, SLOT(quit())); 
    connect(playButton, SIGNAL(clicked()), this, SLOT(emitSig())); 

    ///create the vertical layout 
    QVBoxLayout *layout = new QVBoxLayout; 

    layout->addWidget(playButton); 
    layout->addWidget(infoButton); 
    layout->addWidget(quitButton); 

    setLayout(layout); 
    setWindowTitle(tr("Menu Principale")); 
} 

void MainMenu::emitSig() 
{ 
    emit GoFw(2); 
} 

Спасибо всем ваша помощь, Luca

ответ

1

Я предлагаю переосмыслить ваше решение, кажется, вы перепробовали его с помощью фабричного метода. Просто используйте 3 переменные для форм, выполните «новую» операцию один раз для каждого и используйте методы show()/hide() в зависимости от ваших сигналов.

Чтобы ответить на проблему с крахом, одна из причин, по которой я вижу, - это то, что вы «удаляете» в слот. От Qt doc:

Warning: Deleting a QObject while pending events are waiting to be delivered can cause a crash. You must not delete the QObject directly if it exists in a different thread than the one currently executing. Use deleteLater() instead, which will cause the event loop to delete the object after all pending events have been delivered to it.

Смежные вопросы