Qt5.3/Qt5.12 QMDiArea使用QMdiArea::TabbedView模式有个bug
假设QTabBar有多个tab,当前焦点为tab1,移动tab1的位置,然后切换到桌面,然后重新回到软件,发现焦点不在tab1了
阅读源码,定位到下面代码段,因为不想继续深挖,所以采用一个临时做法,不让QMdiArea执行下面代码段
QMdiArea::eventFilter()
{
//...
QMdiSubWindow *subWindow = qobject_cast<QMdiSubWindow *>(object);
if (!subWindow) {
if (event->type() == QEvent::ApplicationActivate && !d->active
&& isVisible() && !window()->isMinimized()) {
d->activateCurrentWindow();
} else if (event->type() == QEvent::ApplicationDeactivate && d->active) {
d->setActive(d->active, false, false);
}
return QAbstractScrollArea::eventFilter(object, event);
}
//...
}
解决方法:
//mymdiarea.h
#ifndef MYMDIAREA_H
#define MYMDIAREA_H
#include <QWidget>
#include <QMdiArea>
class MyMdiArea : public QMdiArea
{
Q_OBJECT
public:
MyMdiArea(QWidget *parent = 0);
protected:
bool eventFilter(QObject *object, QEvent *event);
};
#endif // MYMDIAREA_H
//mymdiarea.cpp
#include "mymdiarea.h"
#include <QApplication>
#include <QDebug>
#include <QEvent>
#include <QMdiSubWindow>
MyMdiArea::MyMdiArea(QWidget *parent) :
QMdiArea(parent)
{
}
bool MyMdiArea::eventFilter(QObject *object, QEvent *event)
{
/** 优快云 mouze_
* Qt5.3/Qt5.12 QMDiArea使用QMdiArea::TabbedView模式有个bug
* 假设QTabBar有多个tab,当前焦点为tab1,移动tab1的位置,然后切换到桌面,然后重新回到软件,发现焦点不在tab1了
* 阅读源码,定位到下面代码段,因为不想继续深挖,所以采用一个临时做法,不让QMdiArea执行下面代码段
*/
/* QMdiArea::eventFilter中部分代码。
QMdiSubWindow *subWindow = qobject_cast<QMdiSubWindow *>(object);
if (!subWindow) {
if (event->type() == QEvent::ApplicationActivate && !d->active
&& isVisible() && !window()->isMinimized()) {
d->activateCurrentWindow();
} else if (event->type() == QEvent::ApplicationDeactivate && d->active) {
d->setActive(d->active, false, false);
}
return QAbstractScrollArea::eventFilter(object, event);
}
*/
if (event->type() == QEvent::ApplicationActivate)
{
qDebug() << "MyMdiArea::eventFilter ApplicationActive";
return true; // 不执行QMdiArea对这个事件的处理
}
else if (event->type() == QEvent::ApplicationDeactivate)
{
qDebug() << "MyMdiArea::eventFilter ApplicationInactive";
return true;
}
return QMdiArea::eventFilter(object, event);
}
//mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QMdiSubWindow>
#include <mymdiarea.h>
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
private:
MyMdiArea *mdiArea;
};
#endif // MAINWINDOW_H
//mainwindow.cpp
#include "mainwindow.h"
#include <QMdiSubWindow>
#include <QTextEdit>
#include <QDebug>
#include <QApplication>
#include <QTabBar>
#include <mymdiarea.h>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent)
{
resize(600,400);
// 初始化mdiArea
mdiArea = new MyMdiArea;
mdiArea->setViewMode(QMdiArea::TabbedView);
mdiArea->setTabsMovable(true);
mdiArea->setTabsClosable(true);
setCentralWidget(mdiArea);
// 建4个测试子窗口
QString titile = QString("1 tab");
QString text = "I am the " + titile;
QMdiSubWindow *subWin = mdiArea->addSubWindow(new QTextEdit(text));
subWin->setWindowTitle(titile);
QString titile2 = QString("22 tab");
QString text2 = "I am the " + titile2;
QMdiSubWindow *subWin2 = mdiArea->addSubWindow(new QTextEdit(text2));
subWin2->setWindowTitle(titile2);
QString titile3 = QString("333 tab");
QString text3 = "I am the " + titile3;
QMdiSubWindow *subWin3 = mdiArea->addSubWindow(new QTextEdit(text3));
subWin3->setWindowTitle(titile3);
QString titile4 = QString("4444 tab");
QString text4 = "I am the " + titile4;
QMdiSubWindow *subWin4 = mdiArea->addSubWindow(new QTextEdit(text4));
subWin4->setWindowTitle(titile4);
// 当子窗口激活时,移动tab到最左侧
connect(mdiArea, &QMdiArea::subWindowActivated, this, [=](QMdiSubWindow *window)
{
qDebug() << "receive QMdiArea::subWindowActivated signal";
if (window)
{
qDebug() << "\twindow:" << window->windowTitle();
QTabBar *tabBar = mdiArea->findChildren<QTabBar *>().at(0);
int cur = tabBar->currentIndex();
tabBar->moveTab(cur, 0);
}
});
}
MainWindow::~MainWindow()
{
}
//main.cpp
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}