Russian Qt Forum
Ноябрь 18, 2024, 08:02 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Виджет с поведением окна  (Прочитано 4061 раз)
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« : Июнь 19, 2014, 09:58 »

Добрый день

Внутри главного окна есть виджеты которые выглядят как окна, и по смыслу окна и есть. Но, к сожалению, поставить им флаг Qt::Window нельзя т.к. они должны быть внутри главного. Нужно пр нажатии на что угодно внутри такого виджета сделать raise чтобы он перекрыл другие (как окно при активации). Как это лучше реализовать?

- навесить фильтры на все внутренности (не нравится)
- перекрыть notify (лучше но придется отследить модальность и.т.п.)
- более элегантное решение?

Спасибо
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #1 : Июнь 19, 2014, 14:18 »

- навесить фильтры на все внутренности (не нравится)
Почему не нравится? Заведите базовый класс, в котором и навесите фильтры.
Пихать всё в notify, имхо, как-то не серьёзно.
Записан

Qt 5.11/4.8.7 (X11/Win)
kai666_73
Крякер
****
Offline Offline

Сообщений: 319


Просмотр профиля
« Ответ #2 : Июнь 19, 2014, 17:56 »

- навесить фильтры на все внутренности (не нравится)
Почему не нравится? Заведите базовый класс, в котором и навесите фильтры.
Пихать всё в notify, имхо, как-то не серьёзно.

Базовый класс? Оо. А какого типа?
Или имеется ввиду некий класс, который будет микшироваться во все типы виджетов на диалоге главном виджете?
Задачу не облегчит, а проблем добавит, потому-что энтот класс должен наследоваться от QObject.
« Последнее редактирование: Июнь 19, 2014, 18:08 от kai666_73 » Записан
kai666_73
Крякер
****
Offline Offline

Сообщений: 319


Просмотр профиля
« Ответ #3 : Июнь 19, 2014, 18:03 »

- навесить фильтры на все внутренности (не нравится)

А если в самом диалоге виджете-ака-окно после setupUi (или чего там в конструкторе) пробежаться рекурсивно
Код:
parentWidget.findChildren<QWidget *>()
по всем widget-children-м и повесить на каждый фильтр?
« Последнее редактирование: Июнь 19, 2014, 18:12 от kai666_73 » Записан
_OLEGator_
Гость
« Ответ #4 : Июнь 19, 2014, 18:47 »

Я бы использовал QGraphicsView/Scene для такого, нужный функционал там имеется.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #5 : Июнь 19, 2014, 18:54 »

Почему не нравится? Заведите базовый класс, в котором и навесите фильтры.
Как-то "несообразно" - цель довольно мелкая, а тут "целое наследование"

А если в самом диалоге виджете-ака-окно после setupUi (или чего там в конструкторе) пробежаться рекурсивно ... по всем widget-children-м и повесить на каждый фильтр?
Так могут добавляться дынамычно.

И вообще, в случае фильтра raise будет вызываться после события мыши - и это может иметь значение. Напр raise вызовет событие активации меняющее фокус - куда тогда щемиться с текущим событием мыши? Придется опять поизучать исходники.
Записан
kai666_73
Крякер
****
Offline Offline

Сообщений: 319


Просмотр профиля
« Ответ #6 : Июнь 19, 2014, 22:17 »

Дынамично? - флаг в руки, добавляешь - вешай фильтр.

А насчет реализации - можно, наверно, как-то так
Код:
bool MyAutoRaiseWidget::eventFilter(QObject *obj, QEvent *event)
{
  if ( event->type() == QEvent::MouseButtonPress )
    raise();
  return QWidget::eventFilter(obj, event);
}
Не думаю, что raise будет генерить события типа QEvent::MouseButtonPress
« Последнее редактирование: Июнь 19, 2014, 22:28 от kai666_73 » Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #7 : Июнь 20, 2014, 09:44 »

Как-то "несообразно" - цель довольно мелкая, а тут "целое наследование"
Почему Непонимающий
Всё делается просто, вот компилируемый пример ( Qt4.8 ):
Код
C++ (Qt)
#include <QApplication>
#include <QMainWindow>
#include <QMenuBar>
#include <QGridLayout>
#include <QToolBar>
#include <QToolButton>
#include <QGraphicsDropShadowEffect>
 
template< typename T > T findParent( QObject* o )
{
while( o )
{
if( T po = /*qobject_cast*/ dynamic_cast< T >( o ) )
return po;
o = o->parent();
}
return 0;
}
 
class SubWindow : public QMainWindow
{
public:
SubWindow( QWidget* p = 0 )
: QMainWindow( p )
{
setWindowFlags( windowFlags() & ~Qt::Window );
setAutoFillBackground( true );
 
QGraphicsDropShadowEffect* shadow = new QGraphicsDropShadowEffect( this );
shadow->setColor( QColor( 0, 0, 0, 255 ) );
shadow->setOffset( QPointF( 0, 0 ) );
setGraphicsEffect( shadow );
shadow->setBlurRadius( 16 );
 
qApp->installEventFilter( this );
}
protected:
bool eventFilter( QObject* o, QEvent* e )
{
if( e->type() == QEvent::MouseButtonPress && o->isWidgetType() )
{
if( findParent< SubWindow* >( o ) == this )
raise();
}
return QMainWindow::eventFilter( o, e );
}
};
 
class MainWin : public SubWindow
{
public:
MainWin( QWidget* p = 0 )
: SubWindow( p )
{
QMenuBar* mbar = menuBar();
mbar->addMenu( "&File" );
mbar->addMenu( "&View" );
mbar->addMenu( "&Help" );
 
QToolBar* tbar = addToolBar( "" );
for( int i = 0; i < 5; i++ )
tbar->addAction( QString::number( i + 1 ) );
 
QWidget* bw = new QWidget;
QGridLayout* l = new QGridLayout( bw );
for( int r = 0; r < 5; r++ )
for( int c = 0; c < 5; c++ )
{
QToolButton* tb = new QToolButton;
tb->setText( QString( "%1:%2" ).arg( r ).arg( c ) );
l->addWidget( tb, r, c );
}
setCentralWidget( bw );
}
};
 
int main( int argc, char *argv[] )
{
QApplication a( argc, argv );
QWidget w;
QSize sz;
 
for( int i = 0; i < 3; i++ )
{
MainWin* mw = new MainWin( &w );
mw->adjustSize();
mw->move( i * 100 + 20, i * 100 + 20 );
sz = sz.expandedTo( mw->size() );
}
 
w.resize( sz.width() * 2 + 20 , sz.height() * 2 + 20 );
w.show();
return a.exec();
}
 
Записан

Qt 5.11/4.8.7 (X11/Win)
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #8 : Июнь 20, 2014, 10:51 »

Элегантный примерчик, спасибо.
Код
C++ (Qt)
qApp->installEventFilter( this );
 
Ага, сначала фильтр(ы) QCoreApplication получает управление (этого я не знал). Тогда может еще лучше навесить один такой фильтр и в нем искать парента с типом MyWindow?
Записан
GreatSnake
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 2921



Просмотр профиля
« Ответ #9 : Июнь 20, 2014, 10:54 »

Тогда может еще лучше навесить один такой фильтр и в нем искать парента с типом MyWindow?
Ну да, в top-level окне.
Записан

Qt 5.11/4.8.7 (X11/Win)
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.098 секунд. Запросов: 22.