Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > С/С++: Кроссплатформенное программирование, Qt/Gtk+/wxWidgets > MDI приложение, работа с активным окном


Автор: Maxsyuk 13.3.2012, 12:10
Доброго всем времени суток.
Перейду сразу к проблеме. Необходимо создать mdi-приложение, которое работает с графическим представлением. Возникает проблема при попытке работы с активным окном, здесь: 
Код

void MainWindow::slotTest()
{
    qDebug()<<mdiArea->activeSubWindow();
    GraphicsView* view = qobject_cast<GraphicsView*>(mdiArea->activeSubWindow());
    if (view) qDebug()<<"успех";
}


в консоли видим следующее:
Код

QMdiSubWindow(0x15e3330)


Создание mdiArea и добавление subWindow:

Код

//создаем mdiArea
void MainWindow::createMdiArea()
{
    mdiArea = new MdiArea;
    mdiArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
    mdiArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
    setCentralWidget(mdiArea);
    signalMapper = new QSignalMapper(this);
    connect(signalMapper,SIGNAL(mapped(QWidget*)),mdiArea,SLOT(setActiveSubWindow(QMdiSubWindow*)));

}
//создаем subWindow
GraphicsView* MainWindow::createNewGraphicsView()
{
    graphicsViewWindow = new GraphicsView;
    mdiArea->addSubWindow(graphicsViewWindow);
    graphicsViewWindow->setAttribute(Qt::WA_DeleteOnClose);
    graphicsViewWindow->setWindowTitle("Unnamed window");
    return graphicsViewWindow;
}


Теперь нужно разобраться в каком месте я дурак.

Автор: _GRIN_ 13.3.2012, 12:21
Код

void MainWindow::slotTest()
{
    qDebug()<<mdiArea->activeSubWindow();
    GraphicsView* view = qobject_cast<GraphicsView*>(mdiArea->currentSubWindow());
    if (view) qDebug()<<"успех";
}


В лог выводишь activeSubWindow(), а кастишь currentSubWindow()!

Цитата

QMdiSubWindow * QMdiArea::currentSubWindow () const

Returns a pointer to the current subwindow, or 0 if there is no current subwindow.

This function will return the same as activeSubWindow() if the QApplication containing QMdiArea is active.


Может у тебя приложение не активно?

Автор: Maxsyuk 13.3.2012, 17:16
Цитата

В лог выводишь activeSubWindow(), а кастишь currentSubWindow()!

Да нет как раз таки, везде activeSubWindow()

Автор: Maxsyuk 14.3.2012, 08:41
Проблема решена своими руками, оказалось все просто:
Код

qDebug()<<mdiArea->activeSubWindow();
GraphicsView* view = qobject_cast<GraphicsView*>(mdiArea->activeSubWindow()->widget());
if (view) qDebug()<<tr("успех");


Цитата

QObject содержит шаблонную функцию T qobject_cast<T>( QObject* object ), которую можно использовать для проверки и приведения типов. В результате выполнения возвращается указатель на объект класса T, если object является объектом класса T или его потомков. Иначе возвращается 0.

Автор: _GRIN_ 14.3.2012, 08:51
а у тебя GraphicsView - это не наследник от QGraphicsView ?

Автор: Maxsyuk 14.3.2012, 09:04
Как раз таки наследуется от QGraphicsView

Автор: math64 14.3.2012, 10:03
Кстати, проверь в Linux - поведение может отличаться.
Код

    QMdiSubWindow* subWindow = mdiArea->addSubWindow(graphicsViewWindow);
    subWindow->showMaximized(); // Без этого окно может остаться невидимым
    mdiArea->setActiveSubWindow(subWindow); // Без этого activeSubWindow() может вернуть NULL

Поскольку activeSubWindow() может вернуть NULL (например, открытых окон нет), его нужно проверять на NULL.
Вероятно, такую проверку нужно делать в нескольких местах. Можно написать вспомогательную функцию:
Код

GraphicsView* MainWindow::activeGraphicsView()
{
    QMdiSubWindow* subWindow = mdiArea->activeSubWindow();
    if (!subWindow)
        return NULL;
    return qobject_cast<GraphicsView*>(subWindow->widget());
}

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)