Фокусировка окна Qt: главное окно не фокусируется, когда дочернее окно второго уровня закрыто

Прежде всего, извините, если название не имеет никакого смысла.

Так что в основном у меня есть главное окно (QMainWindow экземпляр помечен MainWindow для простоты), который создает дочерний виджет (QWidget экземпляр помечен Widget1) в какой-то момент (для простоты это делается по нажатию кнопки).

void MainWindow::on_pushButton_clicked()
{
    Widget1 *w = new Widget1(this);
    w->show();
}

Widget1 затем создает другой дочерний виджет (QWidget экземпляр помечен Widget2, который отличается от класса Widget1) в какой-то момент (опять же, для простоты, это делается по нажатию кнопки).

Widget1 получает SIGNAL от своего ребенка (Widget2), который используется для отправки другого сигнала своему родителю (MainWindow) и закрываю сам.

void Widget1::on_pushButton_clicked()
{
    Widget2 *w = new Widget2(this);
    connect(w, SIGNAL(testSignalWidget2()), this, SIGNAL(testSignalWidget1()));
    connect(w, SIGNAL(testSignalWidget2()), this, SLOT(close()));
    w->show();
}

После использования Widget2, он испускает SIGNAL его родителю (Widget1), затем закрывается с помощью его this->close() функция.

void Widget2::on_pushButton_clicked()
{
    emit testSignalWidget2();
    this->close();
}

Моя проблема заключается в том, что, как только эта процедура выполнена, фокус окна находится не в MainWindow, а в другом открытом окне. (Если другое окно не открыто, эта процедура отображает панель задач, даже если MainWindow отображается как полноэкранное окно). Для справки, эта проблема возникла только на устройствах Windows; этого не произошло на устройствах Ubuntu, которые я пробовал, которые я использую в качестве основной ОС. Я использовал Qt 4.7.3 на всех устройствах.

И то и другое Widget1 а также Widget2 использует следующие коды для установки своих оконных флагов и модальности:

this->setWindowFlags( Qt::Window | Qt::CustomizeWindowHint );
this->setWindowModality( Qt::WindowModal );

Может кто-нибудь указать, что я делаю не так? Или, может быть, этот подход неправильный с самого начала, кто-нибудь может дать некоторые альтернативы, которые могут сделать те же процедуры?

РЕДАКТИРОВАТЬ: Чтобы ответить на комментарий SaZ, я изменился MainWindowпризыв к Widget1 следующее:

void MainWindow::on_pushButton_clicked()
{
    Widget1 *w = new Widget1(this);
    connect(w, SIGNAL(testSignalWidget1()), this, SLOT(setFocus()));
    w->show();
}

Однако это не повлияло на проблему.

РЕДАКТИРОВАТЬ:

Согласно SaZ, я опубликовал исходный код, который использовал для репликации этой проблемы.

Во-первых, это было начато с автоматически созданного приложения Qt Gui Qt. Widget1 а также Widget2 оба автоматически генерируются как Qt Designer Form Class.

main.cpp

#include <QtGui/QApplication>
#include "mainwindow.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
//    w.show();
    w.showFullScreen();

    return a.exec();
}

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

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

private slots:
    void on_pushButton_clicked();

private:
    Ui::MainWindow *ui;
};

#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"

#include "widget1.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
}

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

void MainWindow::on_pushButton_clicked()
{
    Widget1 *w = new Widget1(this);
    connect(w, SIGNAL(testSignalWidget1()), this, SLOT(setFocus()));
    w->show();
}

widget1.h

#ifndef WIDGET1_H
#define WIDGET1_H

#include <QWidget>

namespace Ui {
class Widget1;
}

class Widget1 : public QWidget
{
    Q_OBJECT

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

signals:
    void testSignalWidget1();
    void testSignalWidget1ToMain();

private slots:
    void on_pushButton_clicked();

private:
    Ui::Widget1 *ui;
};

#endif // WIDGET1_H

widget1.cpp

#include "widget1.h"
#include "ui_widget1.h"

#include "widget2.h"

Widget1::Widget1(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget1)
{
    ui->setupUi(this);

    this->setWindowFlags( Qt::CustomizeWindowHint | Qt::Window );
    this->setWindowModality( Qt::WindowModal );
}

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

void Widget1::on_pushButton_clicked()
{
    Widget2 *w = new Widget2(this);
    connect(w, SIGNAL(testSignalWidget2()),
            this, SIGNAL(testSignalWidget1()));
    connect(w, SIGNAL(testSignalWidget2()),
            this, SLOT(close()));
    w->show();
}

widget2.h

#ifndef WIDGET2_H
#define WIDGET2_H

#include <QWidget>

namespace Ui {
class Widget2;
}

class Widget2 : public QWidget
{
    Q_OBJECT

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

signals:
    void testSignalWidget2();

private slots:
    void on_pushButton_clicked();

private:
    Ui::Widget2 *ui;
};

#endif // WIDGET2_H

widget2.cpp

#include "widget2.h"
#include "ui_widget2.h"

Widget2::Widget2(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget2)
{
    ui->setupUi(this);

    this->setWindowFlags( Qt::CustomizeWindowHint | Qt::Window );
    this->setWindowModality( Qt::WindowModal );
}

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

void Widget2::on_pushButton_clicked()
{
    emit testSignalWidget2();
    this->close();
}

mainwindow.ui, widget1.ui, а также widget2.ui каждый имеет одну кнопку, которые связаны с их соответствующими on_pushButton_clicked() функция.

1 ответ

Решение

Я исправил свою проблему, выполнив следующие действия:

  1. Удалить соединение Widget2"s SIGNAL а также Widget1"s close() функция.
  2. Замените это соединение локальным слотом Widget1,
  3. Вызов Widget1"s close() использовать функцию QTimer::singleshot(),

widget1.h

#ifndef WIDGET1_H
#define WIDGET1_H

#include <QWidget>

namespace Ui {
class Widget1;
}

class Widget1 : public QWidget
{
    Q_OBJECT

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

signals:
    void testSignalWidget1();

private slots:
    void on_pushButton_clicked();
    void testSlot();

private:
    Ui::Widget1 *ui;
};

#endif // WIDGET1_H

widget1.cpp

#include "widget1.h"
#include "ui_widget1.h"

#include "widget2.h"

#include <QTimer>

Widget1::Widget1(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget1)
{
    ui->setupUi(this);

    this->setWindowFlags( Qt::CustomizeWindowHint | Qt::Window );
    this->setWindowModality( Qt::WindowModal );
}

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

void Widget1::on_pushButton_clicked()
{
    Widget2 *w = new Widget2(this);
    connect(w, SIGNAL(testSignalWidget2()),
            this, SIGNAL(testSignalWidget1()));
//    connect(w, SIGNAL(testSignalWidget2()),
//            this, SLOT(close()));
    connect(w, SIGNAL(testSignalWidget2()),
            this, SLOT(testSlot()));
    w->show();
}

void Widget1::testSlot()
{
    QTimer::singleShot(0, this, SLOT(close()));
}
Другие вопросы по тегам