Russian Qt Forum

Qt => Пользовательский интерфейс (GUI) => Тема начата: wertklop от Май 19, 2011, 16:52



Название: MdiSubWindow, не работают слоты
Отправлено: wertklop от Май 19, 2011, 16:52
Всем здравствуйте!
если делать так в программе:
Код:
...
    QWidget*myWidget = new QWidget();
    QPushButton*button = new QPushButton("button", myWidget);
    connect(button,SIGNAL(clicked()),myWidget,SLOT(close()));
    myWidget->show();
...
то вместе с открытием окна программы открывается виджет в виде отдельного окошка и по нажатию кнопки button виджет закрывается. а если делать так:
Код:
... 
    QWidget*myWidget = new QWidget();
    QPushButton*button = new QPushButton("button", myWidget);
    connect(button,SIGNAL(clicked()),myWidget,SLOT(close()));
    mdiArea->addSubWindow(myWidget)->show();
...   
то виджет как и положено, отображается в виде subwindow, но по нажатию кнопки, сама кнопка исчезает, а виджет не закрывается.
как быть?


Название: Re: MdiSubWindow, не работают слоты
Отправлено: lit-uriy от Май 19, 2011, 17:28
>>а виджет не закрывается. как быть?
Виджет как раз закрывается, поэтому исчезает и кнопка.

Тут особенность концепции (на мой взгляд неуклюжей) самого Субокна. Оно остаётся жить.

просто запомни:
resize, close, ... нужно делать для субокна, а не виджета, на основе которого оно создано.

Твой же код, для справки:
Код
C++ (Qt)
mdiArea->addSubWindow(myWidget)->show();
ты вызываешь show() у только что созданного субокна, а не виджета myWidget


Название: Re: MdiSubWindow, не работают слоты
Отправлено: wertklop от Май 20, 2011, 08:32
в принципе, понятно, работает так:
Код:
...
connect(button,SIGNAL(clicked()),mdiArea,SLOT(closeActiveSubWindow()));
...
но как быть, если всё это реализовывать в виде плагина?
исходник плагина plugin.cpp:
Код:
 #include <QtGui>
 #ifdef Q_WS_WIN
 #define MY_EXPORT __declspec(dllexport)
 #else
 #define MY_EXPORT
 #endif
extern "C" MY_EXPORT QWidget* run3()
{  
    QWidget* xWidget = new QWidget();
    xWidget->setWindowTitle("libWidget");
    QPushButton* button = new QPushButton("button", xWidget);
    QWidget::connect(button, SIGNAL(clicked()),xWidget, SLOT(close()));
    return xWidget;
}
исходник программы mainwindow.cpp:
Код:
#include "mainwindow.h"
#include <QtGui>
#include <QLibrary>
#include <QDebug>
MainWindow::MainWindow()
{
...
    loadPlugin = new QAction(this);
    loadPlugin->setText(QString::fromUtf8("&Загрузить плагин"));
    connect(loadPlugin,SIGNAL(triggered()),this,SLOT(LoadPlugin()));
    toolbar->addAction(loadPlugin);
...
}
void MainWindow::LoadPlugin(){

    QLibrary xLibrary("/.../libplugin.so");
    if(xLibrary.load() == false)
        qDebug()<<"fuck library dosn't loaded";
    typedef QWidget*(*MyWidget)();
    MyWidget myWidget = (MyWidget) xLibrary.resolve("run3");
    if (myWidget){
        mdiArea->addSubWindow(((QWidget*)myWidget()))->show();
    }
    else
        qDebug()<<"damn problem with function in lib.... shit";
    xLibrary.unload();
}
если я правильно понимаю, то в плагине у меня опять виджет то закрывается, а вот субокно нет. как бы мне в библиотеке обратиться к субокну?или может просто отслеживать, когда закрывается виджет, закрывать субокно?но тогда вопрос как от новичка, как это отследить?


Название: Re: MdiSubWindow, не работают слоты
Отправлено: lit-uriy от Май 20, 2011, 10:42
первое, что в голову пришло:
ставить на виджет фильтр событий, ловить "Закрытие", если поймано, то закрывать субокно.

П.С.
не забудь, close() для виджета, не удаляет виджет из памяти, т.к. по умолчанию атрибут Qt::WA_DeleteOnClose сброшен.
См.
QMdiSubWindow * QMdiArea::addSubWindow ( QWidget * widget, Qt::WindowFlags windowFlags = 0 )


Название: Re: MdiSubWindow, не работают слоты
Отправлено: lit-uriy от Май 20, 2011, 10:42
П.С.
вообще-то субокно должен пользователь штатным способом закрыавть (крестиком)


Название: Re: MdiSubWindow, не работают слоты
Отправлено: wertklop от Май 20, 2011, 11:20
1)расскажи по конкретнее про фильтр событий, это как?
2)закрывать крестиком это одно, но вот когда в субокне заносятся данные, то кнопочка типа "Ок", которая записывает данные и закрывает субокно, оу как не помешает, если не сказать большее, что это уже как стандарт


Название: Re: MdiSubWindow, не работают слоты
Отправлено: wertklop от Май 20, 2011, 17:14
как оказалось, виджет в субокне живёт "своей жизнью", все действия и события виджета(например, отобразить в полноэкранном режиме) не распостроняются на субокно(каким был размер, таким и остаётся.). можно ли как-нибудь из виджета плагина получить ссылку на его предка(то бишь на субокно, его свойства и методы)?


Название: Re: MdiSubWindow, не работают слоты
Отправлено: lit-uriy от Май 20, 2011, 17:32
>>2)закрывать крестиком это одно, но вот когда в субокне заносятся данные, то кнопочка типа
>>"Ок", которая записывает данные и закрывает субокно, оу как не помешает

Вообще у тебя смысловая ошибка.
Кнопки "Ок" не может быть в субокне. Она для диалогового окна предназначена. Субокно нужно для много документного интерфейса. Диалоговые окна в MDI никто не отменял.


Название: Re: MdiSubWindow, не работают слоты
Отправлено: wertklop от Май 20, 2011, 17:41
так у меня и так многодокументный интерфейс
кстати, по поводу фильтра событий....пробовал, пока не получается, можешь что то посоветовать по последнему моему вопросу?


Название: Re: MdiSubWindow, не работают слоты
Отправлено: wertklop от Май 23, 2011, 15:10
уважаемые форумчане, может всё-таки есть у кого-то мысли по поводу разрешения вопроса в 6м сообщении?буду оч признателен


Название: Re: MdiSubWindow, не работают слоты
Отправлено: Mikhail от Май 23, 2011, 16:04
ПО закрытию своего окна испусти сигнал в QMdiSubWindow в котором оно отображается. Закрытие окна проигнорировать.
Этот сигнал передать сигналом в QMdiArea и оно пумть закроет ативное  QMdiSubWindow в котором отображается видгет в ктором ты нажал кнопку. Вот так.


Название: Re: MdiSubWindow, не работают слоты
Отправлено: wertklop от Май 26, 2011, 09:08
всё оказалось проще. может кому пригодится...
plugin.cpp
Код:
...
extern "C" MY_EXPORT void run3(QMdiArea* parent)
{   
    QWidget* xWidget = new QWidget();
    xWidget->setWindowTitle("libWidget");
    QPushButton* button = new QPushButton("button", xWidget);
    QWidget::connect(button, SIGNAL(clicked()),parent, SLOT(closeActiveSubWindow()));
    parent->addSubWindow(xWidget)->show();
}

mainwindow.cpp
Код:
...
typedef void(*MyWidget)(QMdiArea*);
MyWidget myWidget = (MyWidget) xLibrary.resolve("run3");
    if (myWidget){
        myWidget(mdiArea);
}
...