Базовый графический интерфейс Qt: QPushButton для рисования линии

#qt

#qt

Вопрос:

Я хочу нарисовать сетку (серию линий), когда я нажимаю кнопку рисования, и я хочу, чтобы они очищались, когда я нажимаю кнопку очистки.

Я заставил сетку отображаться как отдельную программу, но я не могу понять, как объединить ее с QPushButton.

Я получаю следующее сообщение при нажатии на кнопку рисования во время работы программы.

«QPainter::begin: возвращенный движок устройства рисования == 0, тип: 1 QPainter ::setPen: Painter не активен»

Спасибо

 #include <QtGui> 
#include <QPainter>
#include "myqtapp.h"

// including <QtGui> saves us to include every class user, <QString>, <QFileDialog>,...

myQtApp::myQtApp(QWidget *parent)
{
    setupUi(this); // this sets up GUI

        // signals/slots mechanism in action
        connect( pushButton_draw, SIGNAL( clicked() ), this, SLOT( draw() ) );
    connect( pushButton_clear, SIGNAL( clicked() ), this, SLOT( clear() ) ); 
    connect( pushButton_about, SIGNAL( clicked() ), this, SLOT( about() ) ); 
}



void myQtApp::draw()
{
    //draw the grid

    int lineSpacing(30),// line spacing in pixels
            numberOfLines;

    QPen pen(Qt::black, 2, Qt::SolidLine);

    QPainter painter(this);
    painter.setPen(pen);

    //Grid takes up at most a 400x400 area starting at (right 150, down 50) from upper left
    numberOfLines = 400/lineSpacing; //Round down grid size to fit in 400x400
    for(int i = 0; i<numberOfLines; i  ){
        painter.drawLine(150, 50 i*lineSpacing, 150 (numberOfLines-1)*lineSpacing, 50 i*lineSpacing);
        painter.drawLine(150 i*lineSpacing, 50, 150 i*lineSpacing, 50 (numberOfLines-1)*lineSpacing );
    }

}
 

Ответ №1:

Проблема, с которой вы столкнулись, заключается в том, что вы пытаетесь рисовать в пользовательском интерфейсе с помощью QPainter вне вызова paintEvent() виджета — из документов Qt :

Обычно QPainter используется внутри события рисования виджета: создайте и настройте (например, установите перо или кисть) художник. Затем нарисуйте. Не забудьте уничтожить объект QPainter после рисования.

Если вы попытаетесь рисовать на виджете вне вызова paintEvent(), результаты будут непредсказуемыми.

Правильный способ сделать это было бы что-то вроде этого:

    // myQtApp.h
   class myQtApp : public QWidget
   {
   Q_OBJECT
   public:
      myQtApp(QWidget *parent = 0); // Constructor as you have
   protected:
      void paintEvent(QPaintEvent *event); // This is re-implemented from QWidget
   protected slots:
      void draw();
   private:
      bool drawTheLines;
   }
 

и

    // myQtApp.cpp
   void myQtApp::paintEvent(QPaintEvent *event)
   {
      QPainter painter(this);

      if(drawTheLines)
      {
         // Do the drawing here - as in your current draw() function
      }

      QWidget::paintEvent(event); // call the base class so everything else is drawn OK
   }


   void draw();
   {
      drawTheLines = true;
      update(); // This forces a repaint of the widget with paintEvent()
   }