Qt bug | QMdiArea使用TabbedView模式下,QTabBar移动tab的一个bug

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)
{
    /** CSDN 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();
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值