Разработаем простой Qt-виджет с нестандартной строкой заголовка. Пока что ограничимся лишь функционалом. Украшательства добавляются с помощью стилей (оставим их на другой раз). В итоге у нас выйдет что-то подобное:
Визуально получить представленный результат очень просто. Достаточно инициализировать наш виджет в конструкторе следующим образом:
1 2 3 4 5 6 7 8 |
DraggableWidget::DraggableWidget( QWidget* parent ) : QWidget( parent, Qt::Window | Qt::FramelessWindowHint ), ui( new Ui::DraggableWidget ) { ui->setupUi( this ); ui->lbTitle->setText( windowTitle() ); connect( ui->btnQuit, SIGNAL( clicked( bool ) ), qApp, SLOT( quit() ) ); } |
Важный момент здесь заключается в указании флагов окна: Qt::Window | Qt::FramelessWindowHint. Все остальное сводится к правильной компоновке элементов на форме.
Для кнопки в правом верхнем углу я включил flat-режим через Qt Designer, чтобы она лучше вписывалась в интерфейс. При этом сигнал нажатия кнопки clicked() привязывается к слоту quit() для приложения.
Но это еще не все. Окно теперь нельзя перемещать с помощью мыши. Добавим такую возможность. А чтобы сделать приложение еще более нестандартным, пусть его можно будет перемещать не только за область заголовка, но и за любое другое место.
Добавим обработчики событий мыши:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
void DraggableWidget::mouseMoveEvent( QMouseEvent* e ) { if( e->buttons() | Qt::LeftButton ) { setGeometry( pos().x() + ( e->x() - dx ), pos().y() + ( e->y() - dy ), width(), height() ); } } void DraggableWidget::mousePressEvent( QMouseEvent* e ) { if( e->button() == Qt::LeftButton ) { dx = e->x(); dy = e->y(); setCursor( Qt::OpenHandCursor ); } } void DraggableWidget::mouseReleaseEvent( QMouseEvent* e ) { if( e->button() == Qt::LeftButton ) { setCursor( Qt::ArrowCursor ); } } |
Немного геометрических расчетов и окно можно двигать. В mousePressEvent() фиксируем начальное положение курсора в системе координат виджета. В mouseMoveEvent() меняем глобальные координаты окна так, чтобы курсор мыши всегда оставался на том же расстоянии от левого верхнего угла виджета.
В качестве дополнительного элемента в обработчиках событий нажатия/отпускания мыши мы меняем курсор на указатель руки, чтобы показать, что виджет находится в состоянии перемещения.