Russian Qt Forum
Ноябрь 25, 2024, 04:59 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: Не выполняется метод QMainWindow::close()  (Прочитано 9421 раз)
stas3638
Гость
« : Ноябрь 08, 2015, 19:24 »

Привет, ребят. Столкнулся с такой вот проблемой, что не закрывается главное окно. Вот в чем суть: в некоторых ситуациях, после закрытия одного из окон, должно закрыться главное окно (MainMenuWnd). Условия закрытия выполняются (спасибо qDebug), но само окно продолжает функционировать. В чем может быть проблема. Вот текст:

Код:
void MainMenuWnd::LoginFinished()
{
    if(currentEmployee == NULL)
    {
        qDebug() << "close MainWnd";
        //this->setHidden(false);
        this->close();
    }
    else
    {/*some code*/}
}
Буду благодарен за любые возможные ответы)
Записан
Vamireh
Гость
« Ответ #1 : Ноябрь 08, 2015, 19:28 »

Ну вообще такое может быть, если это из конструктора вызывается, например.
Записан
stas3638
Гость
« Ответ #2 : Ноябрь 08, 2015, 19:45 »

Ну вообще такое может быть, если это из конструктора вызывается, например.
Тут вызов происходит не из конструктора, это отдельная функция.
Записан
stas3638
Гость
« Ответ #3 : Ноябрь 08, 2015, 20:23 »

Проблема решена посредством плохого кода:
Код:
    QTimer::singleShot(0, this, SLOT(close()));
Может кто-то подскажет более хорошее решение, а то все равно сталкиваюсь с проблемой мигания окна перед закрытием (спасибо методам setHidden). Убрал бы уже скрытие окна, но именно такова постановка задачи на курсовом.
Записан
Bepec
Гость
« Ответ #4 : Ноябрь 08, 2015, 21:10 »

qApp->quit()? Улыбающийся

На деле сложно ответить что у вас не так, т.к. работоспособность метода close зависит от положения в классе. Покажите код, мы вам подскажем решение (ну или скажем "фу какой код" Веселый)
Записан
lit-uriy
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3880


Просмотр профиля WWW
« Ответ #5 : Ноябрь 09, 2015, 06:40 »

stas3638, а если закрывать окно щёлкая по крестику, то оно корректно себя ведёт?
Записан

Юра.
stas3638
Гость
« Ответ #6 : Ноябрь 09, 2015, 15:44 »

stas3638, а если закрывать окно щёлкая по крестику, то оно корректно себя ведёт?
Да, в добавку, есть еще одно кнопка, которая позволяет закрывать окно, там все так же корректно работает.
Записан
Zerkin
Чайник
*
Offline Offline

Сообщений: 98


Просмотр профиля
« Ответ #7 : Ноябрь 10, 2015, 12:46 »

Понятно, что close() работает так:

Цитировать
First it sends the widget a QCloseEvent. The widget is hidden if it accepts the close event. If it ignores the event, nothing happens. The default implementation of QWidget::closeEvent() accepts the close event.

Вы closeEvent()  не переопределяли?
Записан
Vamireh
Гость
« Ответ #8 : Ноябрь 10, 2015, 15:21 »

В общем, минимально рабочий нерабочий пример в студию.
Записан
stas3638
Гость
« Ответ #9 : Ноябрь 10, 2015, 19:34 »

Понятно, что close() работает так:

Цитировать
First it sends the widget a QCloseEvent. The widget is hidden if it accepts the close event. If it ignores the event, nothing happens. The default implementation of QWidget::closeEvent() accepts the close event.

Вы closeEvent()  не переопределяли?

Нет, не переопределял. Если переопределять, то что именно там надо делать? (не надо кидать код, просто словами)
Записан
stas3638
Гость
« Ответ #10 : Ноябрь 10, 2015, 19:49 »

В общем, минимально рабочий нерабочий пример в студию.

LoginWnd.h
Код:
class LoginWnd : public QDialog
{
    Q_OBJECT

public:
    explicit LoginWnd(CEmployee* employee, QWidget *parent = 0);
    ~LoginWnd();

private slots:
    void on_EnterBtn_clicked();

    void CloseWnd();//вот в этом слоте происходит удаление указателя
private:
    Ui::LoginWnd *ui;

    CEmployee *employee;
};

LoginWnd.cpp
Код:
LoginWnd::LoginWnd(CEmployee *employee1, QWidget *parent) :
    QDialog(parent),
    ui(new Ui::LoginWnd)
{
    //...
    employee = employee1;
}
//...
void LoginWnd::CloseWnd()
{
    delete employee;
    employee = NULL;
    this->close();
//обнулил, закрыл, здесь все корректно работает, никаких багов не наблюдалось
}

MainMenuWnd.h
Код:
class MainMenuWnd : public QMainWindow
{
    Q_OBJECT
public:
    explicit MainMenuWnd(QWidget *parent = 0);
    virtual ~MainMenuWnd();
private:
    Ui::MainMenuWnd *ui;
    CEmployee *currentEmployee;
    LoginWnd* LogWnd;
private slots:
    void LoginFinished();//вызывается сразу же, как окно авторизации закрылось
};

MainMenuWnd.cpp
Код:
MainMenuWnd::MainMenuWnd(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainMenuWnd)
{
    ui->setupUi(this);

    currentEmployee = new CEmployee();
//...
    LogWnd = new LoginWnd(currentEmployee);
    connect(
                LogWnd,
                SIGNAL(finished(int)),
                this,
                SLOT(LoginFinished())
                );
    this->hide();
    LogWnd->exec();
}
//...
void MainMenuWnd::LoginFinished()
{
    if(currentEmployee == 0)
    {
        this->setHidden(false);
        this->close();
        //вот тут окно не закрывается. Пробовал и раскрывать/не раскрывать - никаких результатов
        //с помощью qDebug() проверял, что в этот if заходит, когда выполнены соответствующие действия

        //QTimer::singleShot(0, this, SLOT(close()));
        //с помощью таймера решил проблему, но на защите могут из-за него завалить + окошко мигает при закрытии
    }
    else
    {
        //some code
    }
}

Есть еще сигнал у класса CEmployee, который активируется, когда в классе запускается деструктор, но коннектор с этим сигналом так же никак не помог. Стоит учитывать, что окно так же закрывается одним из QAction, и там все работает прекрасно (там, в принципе нечему работать, просто закрывает Веселый ). Просто не могу понять почему такое может возникать, гугл обшарил - ответа не нашел.
Записан
Bepec
Гость
« Ответ #11 : Ноябрь 10, 2015, 20:17 »

конструктор у вас не оканчивает свою работу, а вы свой диалог уже пихаете. Вот и вся проблема в строчке LogWnd->exec();
Записан
stas3638
Гость
« Ответ #12 : Ноябрь 10, 2015, 20:31 »

конструктор у вас не оканчивает свою работу, а вы свой диалог уже пихаете. Вот и вся проблема в строчке LogWnd->exec();
А не могли бы вы посоветовать тогда, как сделать, чтобы окно авторизации запускалось после выполнения конструктора? Как лучше всего поступить в этом случае?
Записан
gil9red
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 1805



Просмотр профиля WWW
« Ответ #13 : Ноябрь 10, 2015, 20:43 »

конструктор у вас не оканчивает свою работу, а вы свой диалог уже пихаете. Вот и вся проблема в строчке LogWnd->exec();
А не могли бы вы посоветовать тогда, как сделать, чтобы окно авторизации запускалось после выполнения конструктора? Как лучше всего поступить в этом случае?

Код авторизации поместите в отдельную функцию (пусть будет auth) и вызывайте после создания окна:
LoginWnd dlg;
dlg.auth();
или
LoginWnd * dlg = new LoginWnd();
dlg->auth();
Записан

Bepec
Гость
« Ответ #14 : Ноябрь 10, 2015, 21:18 »

Ну и да, мини такие уточнения.
Самый простой способ - вызывать таймером синглшотом, из конструктора. Т.е. таймер допустим на 5 мс на вызов auth().
Так же можно сделать вызов в слоте "showEvent" окна, но тогда придётся где то хранить флаг на "однократный" запуск, ибо showEvent вызывается постоянно при открытии/скрытии окна.

PS на деле довольно бесящая штука и не особо очевидная.
Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.054 секунд. Запросов: 22.