Пункты меню “Окно” MDI-приложения

431
20 декабря 2016, 22:24

Как в Qt можно реализовать меню "Окно" MDI-приложения, отражающее открытые внутренние окна и позволяющее переключаться между ними? Пока приходит в голову только добавление QAction при открытии внутреннего окна и удаление этого пункта при закрытии, но как-то геморрно это. Есть ли уже готовые решения в Qt?

Answer 1

У меня реализовано так

GasSolver::GasSolver (QWidget *parent) :
    QMainWindow (parent),
    ui (new Ui::GasSolver)
{
    ui->setupUi (this);
    connect (ui->mWindows, SIGNAL (triggered (QAction *)), this, SLOT  (menu_win_triggered (QAction *)));//выбор окна
    connect (ui->mWindows, SIGNAL (aboutToShow()), this, SLOT (update_winlist()));
}
void GasSolver::menu_win_triggered (QAction *a)
{
    int pos = ui->mWindows->actions().indexOf (a);
    if (pos == -1)
    {
    }
    else if (pos == 0)
    {
        ui->mdiArea->cascadeSubWindows();
    }
    else if (pos == 1)
    {
        ui->mdiArea->tileSubWindows();
    }
    else
    {
        pos -= 3;
        ui->mdiArea->setActiveSubWindow (ui->mdiArea->subWindowList().at (pos));//показать окно
    }
}
void GasSolver::update_winlist()
{
    while (ui->mWindows->actions().count() > 3)
    {
        ui->mWindows->removeAction (ui->mWindows->actions().at (3));
    }
    QList<QMdiSubWindow *> wlist = ui->mdiArea->subWindowList();
    for (qint64 i = 0; i < wlist.size(); i++)
    {
        ui->mWindows->addAction (QString ("%1. %2").arg (i + 1).arg (wlist.at (i)->windowTitle()));
    }
    if (ui->mdiArea->subWindowList().empty())
    {
        ui->WinCascade->setEnabled (false);
        ui->WinMozaik->setEnabled (false);
    }
    else
    {
        ui->WinCascade->setEnabled (true);
        ui->WinMozaik->setEnabled (true);
    }
}

Изначально в меню окна есть пункты каскадом и плиткой

Answer 2

В общем пришел к такому способу (спасибо Evgeny Shmidt за наводку):

void MainWindow::updateWindowsMenu()
{
    while(mnWindows->actions().count()>3)
        mnWindows->removeAction(mnWindows->actions().at(3));
    QList<QMdiSubWindow*> list = mdiArea->subWindowList();
    for(int i=0; i<list.size(); i++){
        mnWindows->addAction(list[i]->windowTitle());
        mnWindows->actions().at(i+3)->setCheckable(true);
        mnWindows->actions().at(i+3)->setStatusTip("Открыть "+list[i]->windowTitle());
        if(list[i]==mdiArea->activeSubWindow())
            mnWindows->actions().at(i+3)->setChecked(true);
        connect(mnWindows->actions().at(i+3), SIGNAL(triggered(bool)), list[i], SLOT(setFocus()));
    }
}   

"3", т.к. первые три пункта меню (cascadeSubWindows(), closeAllSubWindows() и addSeparator()) неизменяемы. Метод делаем слотом и коннектим к сигналу subWindowActivated(QMdiSubWindow*) экземпляра виджета QMdiArea.

READ ALSO
Как добавить путь в REST API на QTcpSocket

Как добавить путь в REST API на QTcpSocket

написал простенький класс который работает как однопоточный http сервер, выдающий текущее время и дату, если обратиться по 1270

320
Как правильно умножить число на десять и прибавить другое число? [требует правки]

Как правильно умножить число на десять и прибавить другое число? [требует правки]

Когда я записываю цифру в переменную, цифра храниться до того момента, покуда я другое значение не запишу, а мне нужно сделать, чтоб старое...

418
Иконка приложения в трее Win 10

Иконка приложения в трее Win 10

При добавлении в трей иконки приложения через метод Shell_NotifyIcon изображение иконки искажается, независимо от размеров изображений вico файле

302