2016-09-06 5 views
0

Я пытаюсь создать простое приложение для рисования - его просто нужно нарисовать, когда вы нажимаете и перетаскиваете курсор (как и Paint). Я знаю, что мне нужно использовать QPainter, но как я могу его обработать? Как это сделать? Любая помощь могла бы быть полезна. Я пробовал скрываться через интернет, но не нашел слишком много информации (я делаю рисование строк и т. Д. Кодом, который запускает приложение, и он здесь, но я не могу найти пример рисования чего-либо пользователем).Как нарисовать, удерживая нажатой кнопку мыши?

ответ

2

Это довольно широкий вопрос, но вот основы:

  1. Сделайте подкласс QWidget класса, так что вы можете изменить некоторые из своих виртуальных методов позже.
  2. Создайте объект вашего подкласса и позвоните по телефону show() (непосредственно перед вызовом QApplication::exec()). Этот объект будет отображаться на экране как очень простое окно, и оно будет служить вашей живописной поверхностью вашего пользователя.
  3. Создайте объект QPixmap, который вы будете использовать для сохранения растрового изображения, которое будет рисовать пользователь. Убедитесь, что размер QPixmap не меньше максимального размера окна, которое вы хотите поддерживать. Заполните fill() на номер QPixmap, чтобы заполнить его с любимым цветом фона.
  4. Переопределения mousePressEvent(QMouseEvent *) метода вашего объекта, чтобы установить логический флаг is_mouse_down, а также для записи текущего положения указателя мыши в окне (по телефону pos() на QMouseEvent объекте, который получает передаваемый в mousePressEvent() вызова и хранении, что в переменную-член вашего объекта).
  5. Переопределить метод mouseMoveEvent(QMouseEvent *) так, что если is_mouse_down_is набор для true, он создает QPainter объект на стеке - передать указатель на QPixmap конструктору QPainter объекта так, что QPainter привлечет в ваш QPixmap объект. Затем вызовите drawLine() на объект QPainter, чтобы нарисовать линию от предыдущей позиции мыши до текущей. Наконец, позвоните update(), чтобы сообщить Qt, чтобы позвонить paintEvent() для вас как можно скорее.
  6. Переопределить метод mouseReleaseEvent(QMouseEvent *) установить is_mouse_down к ложным снова
  7. Override метод paintEvent(QPaintEvent *) создать QPainter объект на стеке - передать указатель на (this) конструктору QPainter объекта, так что он будет рисовать на QWidget напрямую. Затем вызовите drawPixmap() на объект QPainter, чтобы он нарисовал объект QPixmap на видимой поверхности виджета.

Если вы хотите увидеть предварительно написанный пример, ознакомьтесь с приложением Scribble, включенным в Qt, в $QTDIR/examples/widgets/widgets/scribble.

+0

Большое спасибо! Мне действительно удалось сделать что-то вроде этого: он рисовал один пиксель, и этот пиксель исчезал каждый раз.Теперь я знаю, почему и как это делать правильно. Спасибо за ваше время!! – MindRoller

3

Вот ответ Джереми в коде вместо прозы:

// https://github.com/KubaO/stackoverflown/tree/master/questions/simplepaint-39358392 
#include <QtWidgets> 

// Make a subclass of the QWidget class, so that you can override some of its 
// virtual methods 
class PaintWidget : public QWidget { 
    // Create a QPixmap object that you will use to store the bitmap 
    // that the user will draw [on]. 
    QPixmap m_pixmap; 
    QPoint m_lastPos; 
    // Override the paintEvent(QPaintEvent *) [...] 
    void paintEvent(QPaintEvent *) override { 
     QPainter painter{this}; 
     painter.drawPixmap(0, 0, m_pixmap); 
    } 
    void resizeEvent(QResizeEvent *) override { 
     // [...] size the QPixmap to be at least as big as the maximum size of the window 
     // We'll also never let it shrink so as not to lose the already drawn image. 
     auto newRect = m_pixmap.rect().united(rect()); 
     if (newRect == m_pixmap.rect()) return; 
     QPixmap newPixmap{newRect.size()}; 
     QPainter painter{&newPixmap}; 
     painter.fillRect(newPixmap.rect(), Qt::white); 
     painter.drawPixmap(0, 0, m_pixmap); 
     m_pixmap = newPixmap; 
    } 
    // Override the mousePressEvent(QMouseEvent *) [...] 
    void mousePressEvent(QMouseEvent * ev) override { 
     m_lastPos = ev->pos(); 
     draw(ev->pos()); 
    } 
    // Override the mouseMoveEvent(QMouseEvent *) [...] 
    void mouseMoveEvent(QMouseEvent * ev) override { 
     draw(ev->pos()); 
    } 
    void draw(const QPoint & pos) { 
     QPainter painter{&m_pixmap}; 
     painter.setRenderHint(QPainter::Antialiasing); 
     painter.setPen({Qt::blue, 2.0}); 
     painter.drawLine(m_lastPos, pos); 
     m_lastPos = pos; 
     update(); 
    } 
public: 
    using QWidget::QWidget; 
}; 

int main(int argc, char ** argv) { 
    QApplication app{argc, argv}; 
    // Create an object of your subclass and call show() 
    PaintWidget ui; 
    ui.show(); 
    return app.exec(); 
} 

Не нужно переопределить mouseReleaseEvent. В виджета поведение по умолчанию - отслеживать движение мыши только при нажатии кнопки мыши. mouseMoveEvent не будет вызываться, если не нажата кнопка.

+0

Спасибо, я уже создал и создал свою «простую краску». Цените это, хотя. – MindRoller

Смежные вопросы