Regarding the QSplitter, I gave OP the following hint:
Move the right part of the QSplitter into a dock widget (and drop the QSplitter), so that the left part is the only part of the QMainWindow::centralWidget(). This would mean to work with the existing class instead of against, and is probably easier to manage.
OP appreciated the hint with the dock widget but claimed the sub-window will still occupy the whole main window.
I must admit my lack of experience with MDI and made an MCVE to prove me myself right or wrong:
#include <QtWidgets>
// main application
int main(int argc, char **argv)
{
  qDebug() << "Qt Version:" << QT_VERSION_STR;
  QApplication app(argc, argv);
  // setup GUI
  QMainWindow qWinMain;
  qWinMain.setWindowTitle("QMainWindow - MDI - Dock");
  qWinMain.resize(640, 480);
  // MDI
  QMdiArea qMDI;
  qWinMain.setCentralWidget(&qMDI);
  // MDI sub widget
  QLabel qWinSub("MDI Sub-Window\nwidget");
  qMDI.addSubWindow(&qWinSub);
  // Dock
  QDockWidget qDock;
  qDock.setWindowTitle("Dock");
  QLabel qLblDock("Dock\nwidget");
  qDock.setWidget(&qLblDock);
  qWinMain.addDockWidget(Qt::RightDockWidgetArea, &qDock);
  qWinMain.show();
  // runtime loop
  return app.exec();
}
Output:

So, I cannot reproduce OPs claim—it works on my side.
My platform: Windows 10, VS2019, Qt5.15
I enhanced the first MCVE a bit to see how it works if MDI sub-windows are created after qWinMain.show() (what's expected as the usual case).
#include <QtWidgets>
// main application
int main(int argc, char **argv)
{
  qDebug() << "Qt Version:" << QT_VERSION_STR;
  QApplication app(argc, argv);
  // setup GUI
  QMainWindow qWinMain;
  qWinMain.setWindowTitle("QMainWindow - MDI - Dock");
  qWinMain.resize(640, 480);
  // MDI
  QMdiArea qMDI;
  qWinMain.setCentralWidget(&qMDI);
  // Dock
  QDockWidget qWinDock;
  qWinDock.setWindowTitle("Dock");
  QWidget qDock;
  QVBoxLayout qVBoxDock;
  QPushButton qBtnNewMDISubWin("New Sub-Window");
  qVBoxDock.addWidget(&qBtnNewMDISubWin);
  qDock.setLayout(&qVBoxDock);
  qWinDock.setWidget(&qDock);
  qWinMain.addDockWidget(Qt::RightDockWidgetArea, &qWinDock);
  // create sub-window
  int i = 0;
  auto createSubWin = [&]() {
    ++i;
    QLabel* pQWinSub = new QLabel(QString("MDI Sub-Window\nwidget %1").arg(i));
    pQWinSub->setWindowTitle(QString("MDI Sub-Window %1").arg(i));
    qMDI.addSubWindow(pQWinSub);
    pQWinSub->show();
  };
  // install signal handlers
  QObject::connect(&qBtnNewMDISubWin, &QPushButton::clicked,
    createSubWin);
  // runtime loop
  qWinMain.show();
  return app.exec();
}
Output:

It still works on my side as expected.
Note:
I had to add the explicit pQWinSub->show(); after qMDI.addSubWindow(pQWinSub); (which was not necessary in the first MCVE). However, this is exactly how it's done by OP's code.
OPs reply:
It turns out that the problem occurs only when menuBar is present
Oha. How comes?
I extended my MCVE again to add a menu bar:
#include <QtWidgets>
// main application
int main(int argc, char **argv)
{
  qDebug() << "Qt Version:" << QT_VERSION_STR;
  QApplication app(argc, argv);
  // setup GUI
  QMainWindow qWinMain;
  qWinMain.setWindowTitle("QMainWindow - MDI - Dock");
  qWinMain.resize(640, 480);
  // menu
  QMenuBar qMenuMain;
  QAction qCmdFile("File");
  QMenu qMenuFile;
  QAction qCmdFileNew("New");
  qMenuFile.addAction(&qCmdFileNew);
  qCmdFile.setMenu(&qMenuFile);
  qMenuMain.addAction(&qCmdFile);
  qWinMain.setMenuBar(&qMenuMain);
  // MDI
  QMdiArea qMDI;
  qWinMain.setCentralWidget(&qMDI);
  // Dock
  QDockWidget qWinDock;
  qWinDock.setWindowTitle("Dock");
  QWidget qDock;
  QVBoxLayout qVBoxDock;
  QPushButton qBtnNewMDISubWin("New Sub-Window");
  qVBoxDock.addWidget(&qBtnNewMDISubWin);
  qDock.setLayout(&qVBoxDock);
  qWinDock.setWidget(&qDock);
  qWinMain.addDockWidget(Qt::RightDockWidgetArea, &qWinDock);
  // create sub-window
  int i = 0;
  auto createSubWin = [&]() {
    ++i;
    QLabel* pQWinSub = new QLabel(QString("MDI Sub-Window\nwidget %1").arg(i));
    pQWinSub->setWindowTitle(QString("MDI Sub-Window %1").arg(i));
    pQWinSub->setFrameShape(QFrame::Box);
    qMDI.addSubWindow(pQWinSub);
    pQWinSub->show();
  };
  // install signal handlers
  QObject::connect(&qCmdFileNew, &QAction::triggered,
    createSubWin);
  QObject::connect(&qBtnNewMDISubWin, &QPushButton::clicked,
    createSubWin);
  // runtime loop
  qWinMain.show();
  return app.exec();
}
Output:

Note:
I partly agree with OP:
Yes, the look of the maximized MDI is a bit different now. It looks like it occupies the whole client area of the main window but…
…the dock widget is still visible. I added a box to the QLabel (the top widget in the MDI sub-window) to illustrate this. In fact, the sub-window still occupies the central widget only (regardless what the look of its title bar suggests).