Arrow
ArrowMay 5, 2017, 10:04 a.m.

Рисование на QGraphicsScene при зажатой кнопке мыши

QGraphicsScene

Есть QGraphicsScene в которой происходит рисование на загруженной в нее картинке. Нужно дать пользователю возможность рисовать линию из точки А в точку В только при зажатой левой кнопке мыши. Рисование линии должно быть похоже на рисование линии в Paint. Как можно это организовать в Qt.

We recommend hosting TIMEWEB
We recommend hosting TIMEWEB
Stable hosting, on which the social network EVILEG is located. For projects on Django we recommend VDS hosting.

Do you like it? Share on social networks!

8
Evgenii Legotckoi
  • May 5, 2017, 11:27 a.m.

У меня прямо урок есть по рисованию в Qt .

    Arrow
    • May 5, 2017, 1:43 p.m.

    Урок хороший, читал.

    Вопрос в том что при ЛКМ запомнить начальную точку, при перемещении мыши отрисовать прямую линию из начальной точки в текущую позицию курсора, при отпускании ЛК мыши закончить рисование.

    Но при зажатой ЛК мыши не должна рисоваться ломаная (сплошное рисование), а должна рисоваться прямая из нач. точки в новую точку, где теперь находится курсор. Старая же линия должна исчезнуть.

    Вопрос: Как реализовать такое? Основное это как избавиться от старой линии. Просто зарисовать цветом фона не выйдет т. к. фон это изображение загруженное в QGraphicsScene (выбрано пользователем).

    Это, что-то аналогичное функции MS Paint (Gimp, Pinta) - линия (прямая).

      Evgenii Legotckoi
      • May 5, 2017, 1:47 p.m.

      То есть суть в том, что мы нажимаем ЛКМ, на qgraphicsscene появляется линия, один конец которой находится в точке клика, а второй следует за курсором. Как отпускаем ЛКМ, тогда линия и фиксируется как нарисованная? Я правильно понял?

        Arrow
        • May 5, 2017, 2:13 p.m.

        Да

        Извините, случайно выбрал пост как решение.

          Evgenii Legotckoi
          • May 5, 2017, 2:56 p.m.

          Есть у меня кое-какой код, но его нужно ещё найти и выдернуть из проекта. Завтра накидаю пример.

            Arrow
            • May 5, 2017, 3:14 p.m.

            Я подумываю о записи линии с начальной точки в текущую в GroupItem, а затем при перемещении мыши удалении ее оттуда и рисовании новой с начальной точки в новую.

            Только вопрос в том правильно ли это? Возможно есть вариант по лучше.

              Evgenii Legotckoi
              • May 6, 2017, 6:48 a.m.
              • The answer was marked as a solution.

              То есть получается, что объект линии будет постоянно пересоздаваться, так? Лучше будет не пересоздавать объект линии, а устанавливать его форму. При этом алгоритм такой:

              1. При нажатии ЛКМ запоминаем позицию в качестве начальной точки
              2. Поднимаем флаг, что была зажата ЛКМ
              3. Создаём объект линии, и сохраняем указатель на него
              4. При перемещении переустанавливаем форму линии с помощью запомненной первой позиции и текущей позиции курсора.
              5. При отпускании кнопки мыши сбрасываем флаг зажатия ЛКМ.

              В самом простом варианте это реализуется с помощью графической сцены. В более сложном варианте имеет смысл логику по формированию формы выносить в класс линии. Это если типов графических объектов будет достаточно много. Тогда им можно сделать один общий базовый класс с виртуальными методами, которые будут единым интерфейсом взаимодействия с графической сценой. А иначе сама графическая сцена по коду может сильно распухнуть. Но пока приведу пример с графической сценой.

              workplace.h
              #ifndef WORKPLACE_H
              #define WORKPLACE_H
              
              #include <QGraphicsScene>
              
              class QGraphicsSceneMouseEvent;
              class QKeyEvent;
              
              class WorkPlace : public QGraphicsScene
              {
                  Q_OBJECT
                  Q_PROPERTY(QPointF previousPosition READ previousPosition WRITE setPreviousPosition NOTIFY previousPositionChanged)
              
              public:
                  explicit WorkPlace(QObject *parent = 0);
                  ~WorkPlace();
              
                  QPointF previousPosition() const;
                  void setPreviousPosition(const QPointF previousPosition);
              
              signals:
                  void previousPositionChanged();
              
              protected:
                  void mousePressEvent(QGraphicsSceneMouseEvent *event) override;
                  void mouseMoveEvent(QGraphicsSceneMouseEvent *event) override;
                  void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) override;
              
              private:
                  QGraphicsItem *currentItem;
                  QPointF m_previousPosition;
                  bool m_leftMouseButtonPressed;
              };
              
              #endif // WORKPLACE_H
              workplace.cpp
              #include "workplace.h"
              
              #include <QGraphicsSceneMouseEvent>
              #include <QGraphicsLineItem>
              
              WorkPlace::WorkPlace(QObject *parent) :
                  QGraphicsScene(parent),
                  currentItem(nullptr),
                  m_leftMouseButtonPressed(false)
              {
                  setSceneRect(0, 0, 500, 500);
              }
              
              WorkPlace::~WorkPlace()
              {
                  delete currentItem;
              }
              
              QPointF WorkPlace::previousPosition() const
              {
                  return m_previousPosition;
              }
              
              void WorkPlace::setPreviousPosition(const QPointF previousPosition)
              {
                  if (m_previousPosition == previousPosition)
                      return;
              
                  m_previousPosition = previousPosition;
                  emit previousPositionChanged();
              }
              
              void WorkPlace::mousePressEvent(QGraphicsSceneMouseEvent *event)
              {
                  if (event->button() & Qt::LeftButton) {
                      m_leftMouseButtonPressed = true;
                      setPreviousPosition(event->scenePos());
                      QGraphicsLineItem *line = new QGraphicsLineItem();
                      currentItem = line;
                      addItem(currentItem);
                      line->setLine(QLineF(m_previousPosition, m_previousPosition));
                  }
              }
              
              void WorkPlace::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
              {
                  if (m_leftMouseButtonPressed) {
                      QGraphicsLineItem *line = qgraphicsitem_cast<QGraphicsLineItem *>(currentItem);
                      line->setLine(QLineF(m_previousPosition, event->scenePos()));
                  }
              }
              
              void WorkPlace::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
              {
                  if (event->button() & Qt::LeftButton) {
                      m_leftMouseButtonPressed = false;
                  }
              }
                Arrow
                • May 10, 2017, 5:47 a.m.

                Спасибо!

                  Comments

                  Only authorized users can post comments.
                  Please, Log in or Sign up
                  AD

                  C ++ - Test 004. Pointers, Arrays and Loops

                  • Result:50points,
                  • Rating points-4
                  m

                  C ++ - Test 004. Pointers, Arrays and Loops

                  • Result:80points,
                  • Rating points4
                  m

                  C ++ - Test 004. Pointers, Arrays and Loops

                  • Result:20points,
                  • Rating points-10
                  Last comments
                  i
                  innorwallNov. 12, 2024, 6:12 a.m.
                  Django - Tutorial 055. How to write auto populate field functionality Freckles because of several brand names retin a, atralin buy generic priligy
                  i
                  innorwallNov. 12, 2024, 2:23 a.m.
                  QML - Tutorial 035. Using enumerations in QML without C ++ priligy cvs 24 Together with antibiotics such as amphotericin B 10, griseofulvin 11 and streptomycin 12, chloramphenicol 9 is in the World Health Organisation s List of Essential Medici…
                  i
                  innorwallNov. 11, 2024, 11:50 p.m.
                  Qt/C++ - Lesson 052. Customization Qt Audio player in the style of AIMP It decreases stress, supports hormone balance, and regulates and increases blood flow to the reproductive organs buy priligy online safe Promising data were reported in a PDX model re…
                  i
                  innorwallNov. 11, 2024, 10:19 p.m.
                  Heap sorting algorithm The role of raloxifene in preventing breast cancer priligy precio
                  i
                  innorwallNov. 11, 2024, 9:55 p.m.
                  PyQt5 - Lesson 006. Work with QTableWidget buy priligy 60 mg 53 have been reported by Javanovic Santa et al
                  Now discuss on the forum
                  i
                  innorwallNov. 12, 2024, 4:56 a.m.
                  добавить qlineseries в функции buy priligy senior brother Chu He, whom he had known for many years
                  i
                  innorwallNov. 11, 2024, 6:55 p.m.
                  Всё ещё разбираюсь с кешем. priligy walgreens levitra dulcolax carbs The third ring was found to be made up of ultra relativistic electrons, which are also present in both the outer and inner rings
                  9
                  9AnonimOct. 25, 2024, 4:10 p.m.
                  Машина тьюринга // Начальное состояние 0 0, ,<,1 // Переход в состояние 1 при пустом символе 0,0,>,0 // Остаемся в состоянии 0, двигаясь вправо при встрече 0 0,1,>…

                  Follow us in social networks