Qt Window 聚焦:Main window 关闭时 second-level child window 不聚焦

Qt Window Focusing: Main window is not focused when second-level child window is closed

首先,如果标题没有任何意义,请见谅。

所以基本上,我有一个主要的 window(为简单起见标记为 MainWindowQMainWindow 实例),它创建了一个 child 小部件(QWidget 实例在某些时候标记为 Widget1)(为简单起见,这是通过单击按钮完成的)。

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

Widget1 然后创建另一个 child 小部件(QWidget 标记为 Widget2 的实例,它与 Widget1 不同 class)一些点(同样,为简单起见,这是通过单击按钮完成的)。

Widget1 从它的 child (Widget2) 接收到一个 SIGNAL,用于向它的 parent (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 后,它向其 parent (Widget1) 发出一个 SIGNAL,然后使用其 this->close() 函数关闭。

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

我的问题是,完成此过程后,window 焦点不在 MainWindow 中,而是在另一个打开的 window 上(如果没有打开其他 window,则此程序显示任务栏,即使 MainWindow 显示为全屏 window)。作为参考,此问题仅发生在 Windows 台设备上;这在我试过的 Ubuntu 单元上没有发生,我将其用作主要 OS。我在所有单元上都使用了 Qt 4.7.3。

Widget1Widget2 都使用以下代码来设置它们的 window 标志和模式:

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 的 auto-generated Qt Gui 应用程序开始的。 Widget1Widget2 都是 auto-generated 作为 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.uiwidget1.uiwidget2.ui 各有一个按钮,连接到各自的 on_pushButton_clicked() 功能。

我已通过执行以下操作解决了我的问题:

  1. 删除Widget2SIGNALWidget1close()函数的连接。
  2. Widget1 的本地插槽替换该连接。
  3. 使用QTimer::singleshot()调用Widget1close()函数。

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