Implementación de una barra de herramientas dual en QT

Enlace al código fuente





Desafío y requisitos

  • Creación de una doble "barra de herramientas" (barra de herramientas), cuya posición del separador cambiaría la relación de los campos del divisor.

    En otras palabras, el separador debe arrastrarse con el mouse.





  • La posición del divisor de la barra de herramientas también debe depender de la posición del divisor.





  • Al pasar el cursor sobre el separador de la barra de herramientas, el tipo de cursor debe cambiar a QT horizontal :: SizeHorCursor





  • Al arrastrar el separador, el cursor también debe cambiar su tipo a 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 cambio de tamaño de ventana. On_splitter_splitterMoved no se puede llamar en este evento, por lo tanto, es necesario hacer que el temporizador, que "irá más allá" del resizeEvent, funcione fuera de él.





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 cambia el tamaño de la barra de herramientas a través de on_splitter_splitterMoved. Cuando se cambia el tamaño de la ventana, la posición del divisor se determina automáticamente





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;
}
      
      






All Articles