Версия для печати темы
Форум на CrossPlatform.RU _ Qt GUI _ QWidget без заголовка,но меняющий размеры?
Автор: a_goodgirl 4.6.2009, 17:59
Нужно, чтобы QWidget "выпадал" как меню - т.е. имел вид "без заголовка" (см. картинку). Сделать это можно с помощью
setWindowFlags(Qt::Popup);
Но при этом окно становится не способным менять размер, а нужно его растягивать!
Автор: kwisp 4.6.2009, 20:34
Цитата(a_goodgirl @ 4.6.2009, 18:59)
setWindowFlags(Qt::Popup);
Но при этом окно становится не способным м
вроде не только таким флагом
Автор: sendevent 4.6.2009, 21:04
возможно, поможет связка QMenu+QWidgetAction+QWidget, и в QWidget::sizeHint() - определять оптимальный размер виджета? .
если же топлевел фреймлесс виджет нужен обязательно - изменения геометрии надо самостоятельно реализовать, примерно так:
(реализовано омерзительно, сделать все по человечески - руки не доходят, так што звыняйте)
CODE
/*virtual*/ void FramelessWidget::mousePressEvent( QMouseEvent *event )
{
m_ptPrevPos = event->globalPos();
//-- m_eUIState - our enum:
if( m_eUIState == UIS_NONE )
{
if( canHorResize( m_ptPrevPos ) )
{
m_eUIState = UIS_RESIZE_HOR;
}
else if( canVerResize( m_ptPrevPos ) )
{
m_eUIState = UIS_RESIZE_VER;
}
//-- ui.pTitleWidget - TitleBar "emulator"
else if( ui.pTitleWidget->rect().contains( ui.pTitleWidget->mapFromGlobal( m_ptPrevPos ) ) )
{
m_eUIState = UIS_MOVE;
}
else
{
m_eUIState = UIS_NONE;
}
}
QWidget::mouseReleaseEvent( event );
}
/*virtual*/ void FramelessWidget::mouseReleaseEvent( QMouseEvent *event )
{
m_eUIState = UIS_NONE;
setCursor( Qt::ArrowCursor );
QWidget::mouseReleaseEvent( event );
}
/*virtual*/ void FramelessWidget::mouseMoveEvent( QMouseEvent *event )
{
QPoint click = event->globalPos();
if( qApp->keyboardModifiers() == Qt::NoModifier
&& event->buttons() == Qt::LeftButton )
{
if( m_eUIState == UIS_RESIZE_VER )
{
resizeVertical( click );
}
else if( m_eUIState == UIS_RESIZE_HOR )
{
resizeHorizontal( click );
}
else if( m_eUIState == UIS_MOVE )
{
QRect currentGeom = geometry();
QPoint newPos = mapToGlobal( this->pos() );
QPoint delta = click - m_ptPrevPos;
newPos += delta;
currentGeom.moveTo( mapFromGlobal( newPos ) );
setGeometry( currentGeom );
}
}
else
{
if( canVerResize( click ) )
{
setCursor( Qt::SizeVerCursor );
}
else if( canHorResize( click ) )
{
setCursor( Qt::SizeHorCursor );
}
else
{
setCursor( Qt::ArrowCursor );
}
}
m_ptPrevPos = click;
QWidget::mouseMoveEvent( event );
}
bool FramelessWidget::canHorResize( const QPoint& cursorPos )
{
int cursX = cursorPos.x();
int myX = pos().x();
int myW = width();
int resizePrec = 5;
if( ( cursX >= myX-resizePrec && cursX <= myX+resizePrec )
|| ( cursX >= myX+myW-resizePrec && cursX <= myX+myW+resizePrec ) )
{
return true;
}
return false;
}
bool FramelessWidget::canVerResize( const QPoint& cursorPos )
{
int cursY = cursorPos.y();
int myY = pos().y();
int myH = height();
int resizePrec = 5;
if( ( cursY >= myY-resizePrec && cursY <= myY+resizePrec )
|| ( cursY >= myY+myH-resizePrec && cursY <= myY+myH+resizePrec ) )
{
return true;
}
return false;
}
void FramelessWidget::resizeHorizontal( const QPoint& newPos )
{
QPoint me = pos();
int middleX = pos().x() +width()/2;
int delta = newPos.x() - m_ptPrevPos.x();
QRect geom = geometry();
if( newPos.x() > middleX )
{//-- right border used:
geom.setWidth( width()+delta );
}
else
{
QPoint topL = geom.topLeft();
topL.setX( topL.x() + delta );
geom.setTopLeft( topL );
geom.setWidth( width()-delta );
}
setGeometry( geom );
}
void FramelessWidget::resizeVertical( const QPoint& newPos )
{
QPoint me = pos();
int middleY = pos().y() +height()/2;
int delta = newPos.y() - m_ptPrevPos.y();
QRect geom = geometry();
if( newPos.y() > middleY )
{
geom.setHeight( height()+delta );
}
else
{
QPoint topL = geom.topLeft();
topL.setY( topL.y() + delta );
geom.setTopLeft( topL );
geom.setHeight( height()-delta );
}
setGeometry( geom );
}
Автор: SABROG 5.6.2009, 8:56
А добавить на форму QSizeGrip вера не позволяет?
Автор: a_goodgirl 5.6.2009, 12:00
Цитата(SABROG @ 5.6.2009, 9:56)
А добавить на форму QSizeGrip вера не позволяет?
Большое спасибо за QSizeGrip! С помощью гугления найти его использование удалось только для комбобокса. Но вроде там все просто:
в класс
class ContourFilterDialog: public QWidgetв конструктор добавлено:
QSizeGrip *sgrip = new QSizeGrip(this);Но при этом уголок для растягивания появляется в
левом верхнем углу! (и окно растягивается тоже вверх и влево). Хотя в документации написано:
"Resize grips are usually rendered as small diagonal textured lines in the
lower-right corner."
Если нетрудно помочь - как управлять расположением уголка?
Автор: SABROG 5.6.2009, 12:53
Попробуй так:
QSizeGrip *sgrip = new QSizeGrip(this);
sgrip->move(geometry().bottomRight());
updateGeometry();
Автор: a_goodgirl 5.6.2009, 17:40
Большое спасибо SABROG!!!
В целом работает, с небольшими поправками:
надо перемещать не в угол, а в
_sgrip->move(QPoint(width()-_sgrip->width(), height()-_sgrip->height()));
и еще приходится отслеживать resizeEvent и делать там то же самое, а то уголок "теряется"
Автор: Litkevich Yuriy 5.6.2009, 17:47
Цитата(a_goodgirl @ 5.6.2009, 21:40)
Большое спасибо SABROG!!!
а ты ему "Спасибо" нажми
С этим уголком не работал, но похоже что куча ручной работы обусловлена как раз тем, что декорации окна нет и уголку некчему липнуть.
Надо будет его исходник глянуть.
Автор: SABROG 5.6.2009, 18:01
Как мне кажется, нужно добавить на форму layout, поместить на него QSizeGrip и вызвать bool QLayout::setAlignment ( QWidget * w, Qt::Alignment alignment )
Автор: a_goodgirl 9.6.2009, 13:08
предложение SABROG, в целом работающее верно, в частности дало странный результат:
_sgrip = new QSizeGrip(this);
_gridLayout->addWidget(_sgrip);
_gridLayout->setAlignment(_sgrip, Qt::AlignRight | Qt::AlignBottom);
Уголок прицепился снизу, НО посередине, несмотря на значение
Alignment. Если же задать
Qt::AlignLeft, то слева почему-то прикрепляется корректно. При этом resize event отслеживать действительно не надо.
Автор: SABROG 9.6.2009, 15:45
Вот:
QSizeGrip *sg = new QSizeGrip(dialog);
QVBoxLayout *vbl = new QVBoxLayout(dialog);
QHBoxLayout *hbl = new QHBoxLayout;
vbl->setSpacing(0);
vbl->setMargin(0);
hbl->addStretch();
hbl->addWidget(sg);
vbl->addLayout(hbl);
Автор: a_goodgirl 10.9.2009, 14:36
прошу прощения за длительный перерыв.
Навалились другие окна. Но пришло время использовать этот диалог, в котором никак не вставал на место уголок для растягивания. С удивлением сегодня увидела, что он так и не работает :-) Списала выше слова - все стало OK. Спасибо!
Форум Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)