QToolbar в QMainWindow - сигнализировать панели инструментов об изменении ее положения

Я хотел бы иметь возможность обнаруживать любые изменения как в положении, так и в ориентации панели инструментов, которая является частью главного окна. На панели инструментов есть QPushButton кнопка nodes_button, которая является частью главного окна. Я использую как QMainWindow, так и QToolBar по умолчанию. nodes_button содержит QMenu, и целью всего этого упражнения является размещение индикатора меню nodes_button таким образом, чтобы он визуально соответствовал панели инструментов.

Панель инструментов по умолчанию в главном окне по умолчанию имеет 5 мест, где она может быть размещена — сверху, снизу, слева, справа и плавающая. В зависимости от области, где расположена панель инструментов, она также меняет свою ориентацию на горизонтальную (плавающую, сверху и снизу) или вертикальную (слева или справа).

Определить ориентацию несложно, так как панели инструментов фактически предоставляют QToolBar::orientation() (для получения ориентации) и QToolBar::orientationChanged(Qt::Orientation) (сигнал, испускаемый каждый раз, когда ориентация панели инструментов изменяется). Используя сигнал, я могу подключить слот следующим образом:

connect(toolbar, SIGNAL(orientationChanged(Qt::Orientation)), this, SLOT(toolbarAdjust()));

В настоящее время toolbarAdjust() запускается только при изменении ориентации панели инструментов, однако я также хочу использовать ее при изменении местоположения панели инструментов:

void MainWindow::toolbarAdjust()
{
  Qt::Orientation toolbarOrientation = toolbar->orientation();
  Qt::ToolBarArea toolbarPosition = this->toolBarArea(toolbar);

  if(toolbarOrientation == Qt::Horizontal) {
    if(toolbarPosition == Qt::NoToolBarArea || toolbarPosition == Qt::TopToolBarArea) {
      nodes->setStyleSheet("QPushButton#nodes_button::menu-indicator {image: url(:node_menu_top); subcontrol-position: bottom center; subcontrol-origin: padding; bottom: -7px}");
    }
    else if(toolbarPosition == Qt::BottomToolBarArea) {
      nodes->setStyleSheet("QPushButton#nodes_button::menu-indicator {image: url(:node_menu_bottom); subcontrol-position: top center; subcontrol-origin: padding; top: -7px}");
    }
  }
  else if (toolbarOrientation == Qt::Vertical) {
    if(toolbarPosition == Qt::LeftToolBarArea) {
      nodes->setStyleSheet("QPushButton#nodes_button::menu-indicator {image: url(:node_menu_right); subcontrol-position: left center; subcontrol-origin: padding; right: -6px;}");
    }
    else if(toolbarPosition == Qt::RightToolBarArea) {
      nodes->setStyleSheet("QPushButton#nodes_button::menu-indicator {image: url(:node_menu_left); subcontrol-position: right center; subcontrol-origin: padding; left: -6px;}");
    }
  }
}

Это не всегда работает по многим причинам, например из-за того, что и для левой, и для правой/верхней и нижней области панели инструментов ориентация панели инструментов одинакова - вертикальная/горизонтальная.

Итак, мне нужно что-то вроде

connect(this, SIGNAL(toolbarLocationChanged()), this, SLOT(toolbarAdjust()));

Используя ориентацию и расположение панели инструментов, я могу разместить индикатор меню таким образом, чтобы он соответствовал текущему местоположению панели инструментов. Как вы можете видеть ниже, ориентация в сочетании с соответствующей вариацией таблицы стилей

QPushButton#nodes_button::menu-indicator {
  image: url(:node_menu_top);         // bottom, right, left
  subcontrol-position: bottom center; // top, right, left
  subcontrol-origin: padding;
  bottom: -7px                        // top, left, right
}

приводит к

введите здесь описание изображения введите здесь описание изображения введите здесь описание изображения введите здесь описание изображения

На самом деле я могу опустить всю часть ориентации и сделать следующее:

void MainWindow::toolbarAdjust()
{
  Qt::ToolBarArea toolbarPosition = this->toolBarArea(drawingToolBar);

  switch(toolbarPosition) {
    case Qt::NoToolBarArea:;
    case Qt::TopToolBarArea:
      nodes->setStyleSheet("QPushButton#nodes_button::menu-indicator {image: url(:node_menu_top); subcontrol-position: bottom center; subcontrol-origin: padding; bottom: -7px}");
      break;
    case Qt::BottomToolBarArea:
      nodes->setStyleSheet("QPushButton#nodes_button::menu-indicator {image: url(:node_menu_bottom); subcontrol-position: top center; subcontrol-origin: padding; top: -7px}");
      break;
    case Qt::LeftToolBarArea:
      nodes->setStyleSheet("QPushButton#nodes_button::menu-indicator {image: url(:node_menu_right); subcontrol-position: left center; subcontrol-origin: padding; right: -6px;}");
      break;
    case Qt::RightToolBarArea:
      nodes->setStyleSheet("QPushButton#nodes_button::menu-indicator {image: url(:node_menu_left); subcontrol-position: right center; subcontrol-origin: padding; left: -6px;}");
      break;
  }
}

из-за того, как ведет себя панель инструментов, когда вы ее закрепляете/плаваете.

EDIT: я нашел этот пост, где пользователь сообщает ОП о QDockWidget::dockLocationChanged() и о том, что, возможно, такая функциональность была добавлена ​​и к QToolBar. В конце OP публикует электронное письмо, которое показывает, что такая функция была запрошена. Пост от 2007 года...


person rbaleksandar    schedule 14.03.2016    source источник


Ответы (1)


Я обнаружил, что сигнал QToolBar::topLevelChanged(bool) помогает мне решить проблему. Всякий раз, когда пользователь хочет изменить область панели инструментов на панели инструментов, он / она должен щелкнуть панель инструментов, перетащить ее в эту область, а затем отпустить. На основе документации Qt:

Этот сигнал испускается при изменении плавающего свойства. Параметр topLevel имеет значение true, если панель инструментов теперь плавающая; в противном случае это ложь.

Поэтому всякий раз, когда пользователь перетаскивает панель инструментов, она, очевидно, также плавает. Как только панель инструментов закреплена, она не плавает. Обнаружение этого изменения в плавающем свойстве панели инструментов можно использовать для настройки ее содержимого.

Вот результат, если кому интересно:

Верхнее место (индикатор направлен вниз)

введите здесь описание изображения

Нижнее размещение (индикатор указывает вверх)

введите здесь описание изображения

Место размещения слева (индикатор указывает вправо)

введите здесь описание изображения

Правильное размещение (индикатор указывает влево)

введите здесь описание изображения

person rbaleksandar    schedule 14.03.2016