Desafio e requisitos
Criação de uma "barra de ferramentas" dupla (barra de ferramentas), cuja posição do separador mudaria a proporção dos campos do divisor.
Em outras palavras, o separador deve ser arrastado com o mouse.
A posição do divisor da barra de ferramentas também deve depender da posição do divisor.
Ao passar o mouse sobre o separador da barra de ferramentas, o tipo de cursor deve mudar para horizontal QT :: SizeHorCursor
Ao arrastar o separador, o cursor também deve mudar seu tipo para horizontal
,
Qt Widgets application. cpp h , , .
Object Inspector
.
toolbar , . .
MainWindow, centralwidget Mouse tracking, true. , .
, , . 200 . childrenCollapsible, false. , "" . : cpp .
movable, false, .
MainWindow.h
private:
Ui::MainWindow *ui;
int timerId = 0;
bool toolbar_dragged = false;
Ui::MainWindow *ui : timerId toolbar_dragged.
timerId , .
toolbar_dragged :
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
void on_splitter_splitterMoved(int pos, int index, bool windowResized = true);
void mouseMoveEvent(QMouseEvent *event);
void mouseReleaseEvent(QMouseEvent *e);
void mousePressEvent(QMouseEvent *event);
void timerEvent(QTimerEvent *event);
void resizeEvent(QResizeEvent* event);
on_splitter_splitterMoved windowResized, , , true. resizeEvent, , on_splitter_splitterMoved emit. , . , toolbar_dragged == false. , , . cpp .
MainWindow.cpp
:
QMouseEvent
QWidget
#include <QMouseEvent>
#include <QWidget>
:
centralWidget()->layout()->setContentsMargins , layout-, .
setSpacing(2) , MainWindow, 2 , .
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
centralWidget()->layout()->setContentsMargins(0, 0, 0, 0);
//this is nessesary
this->ui->toolBar_2->layout()->setSpacing(2);
}
on_splitter_splitterMoved . . , . resize move .
, , , , , , - . , , QT .
void MainWindow::on_splitter_splitterMoved(int pos, int /*index*/, bool windowResized)
{
if (((pos>this->ui->listWidget->minimumSize().width()) &&
(pos<(this->width() - this->ui->listWidget_2->minimumSize().width()))) || windowResized)
{
this->ui->toolBar->setMaximumSize(pos, ui->toolBar->rect().height());
this->ui->toolBar->setMinimumSize(pos, ui->toolBar->rect().height());
}
}
mouseReleaseEvent , . Qt::ArrowCursor toolbar_dragged, false.
void MainWindow::mouseReleaseEvent(QMouseEvent* /*e*/)
{
if (toolbar_dragged)
{
toolbar_dragged = false;
this->setCursor(Qt::ArrowCursor);
}
}
mousePressEvent .
, +-20 , , toolbar_dragged true, .
void MainWindow::mousePressEvent(QMouseEvent *event)
{
QList<int> currentSizes = this->ui->splitter->sizes();
if ((this->ui->toolBar_2->underMouse()) &&
(event->buttons() == Qt::LeftButton) &&
(event->pos().x() < (currentSizes[0]+20)))
{
this->ui->toolBar_2->movableChanged(true);
toolbar_dragged = true;
this->setCursor(Qt::SizeHorCursor);
}
else if ((this->ui->toolBar->underMouse()) &&
(event->buttons() == Qt::LeftButton) &&
(event->pos().x() > (currentSizes[0]-20)))
{
this->ui->toolBar->movableChanged(true);
toolbar_dragged = true;
this->setCursor(Qt::SizeHorCursor);
}
}
mouseMoveEvent . (toolbar_dragged), on_splitter_splitterMoved , .
, , -2 +5 , , , SizeHorCursor. , SizeHorCursor ArrowCursor, Mouse tracking , true, .
void MainWindow::mouseMoveEvent(QMouseEvent* event)
{
QList<int> currentSizes = this->ui->splitter->sizes();
if (toolbar_dragged)
{
QList<int> currentSizes = this->ui->splitter->sizes();
currentSizes[0] = event->pos().x();
currentSizes[1] = this->width() - event->pos().x();
this->ui->splitter->setSizes(currentSizes);
emit on_splitter_splitterMoved(event->pos().x(), 1, false);
}
else if ((event->pos().y() > (2+this->ui->toolBar->y())) &&
(event->pos().y() < (this->ui->toolBar->height()-2+this->ui->toolBar->y())) &&
(event->pos().x() < (currentSizes[0]+5)) &&
(event->pos().x() > (currentSizes[0]-10)))
{
this->setCursor(Qt::SizeHorCursor);
}
else
{
this->setCursor(Qt::ArrowCursor);
}
}
resizeEvent - evento de redimensionamento da janela. On_splitter_splitterMoved não pode ser chamado neste evento, portanto é necessário fazer com que o timer, que irá "ir além" do resizeEvent, funcione fora dele.
void MainWindow::resizeEvent(QResizeEvent* event)
{
if (timerId)
{
killTimer(timerId);
timerId = 0;
}
// delay beetween ends of resize and your action
timerId = startTimer(1);
QMainWindow::resizeEvent(event);
}
timerEvent redimensiona a barra de ferramentas por meio de on_splitter_splitterMoved. Quando a janela é redimensionada, a posição do divisor é determinada automaticamente
void MainWindow::timerEvent(QTimerEvent *event)
{
QList<int> currentSizes = this->ui->splitter->sizes();
this->ui->toolBar_2->adjustSize();
emit on_splitter_splitterMoved(currentSizes[0], 1,true);
killTimer(event->timerId());
timerId = 0;
}