QTでのデュアルツールバーの実装

ソースコードへのリンク





課題と要件

  • 二重の「ツールバー」(ツールバー)を作成します。そのセパレータの位置によって、スプリッタのフィールドの比率が変更されます。

    つまり、セパレータはマウスでドラッグする必要があります。





  • ツールバーの仕切りの位置は、スプリッターの位置にも依存する必要があります。





  • ツールバーの区切り文字にカーソルを合わせると、カーソルの種類が水平QT :: SizeHorCursorに変わります。





  • セパレータをドラッグするときは、カーソルのタイプも水平に変更する必要があります





  • ,









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-ウィンドウサイズ変更イベント。このイベントではOn_splitter_splitterMovedを呼び出すことができないため、resizeEventを「超える」タイマーをその外部で機能させる必要があります。





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は、on_splitter_splitterMovedを介してツールバーのサイズを変更します。ウィンドウのサイズが変更されると、スプリッタスプリッタの位置が自動的に決定されます





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