Как рисовать на QLabel с каждым выпуском QTimer - PullRequest
0 голосов
/ 04 апреля 2019

Моя цель - использовать QLabel с каждым выпуском QTimer. Вот как я пытаюсь добиться этого:

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

void ImageViewer::on_measuresAct_triggered()

    {
        dialog = new Measures;
        dialog->show();
        Ymax = Origin = Xmax = QPoint(30,30);
        measuresflag = true;
        pixtemp = imageLabel->pixmap();
        timer = new QTimer;
        connect(timer, SIGNAL(timeout()), this, SLOT(drawontimer()));
        timer->start(100);
        if(!dialog->isVisible())
            timer->stop();
    }

Вот слот для рисования мер.

void ImageViewer::drawontimer()
{

    pixmap = pixtemp;
qDebug()<<"Hey there";
    pix = (*pixmap);

    QPainter paint(&pix);

    QPen MeasurePen (Qt::magenta);
    MeasurePen.setWidth(5);
    QBrush MeasureBrush (Qt::magenta,Qt::SolidPattern);
    paint.setPen(MeasurePen);
    paint.setBrush(MeasureBrush);


    paint.drawLine(Ymax,Origin);
    paint.drawLine(Origin, Xmax);



    QString originpoint = "(" + dialog->ui->olinex->text() + ", " + dialog->ui->oliney->text() + ")";
    QString xmaxpoint = "(" + dialog->ui->xline->text() + ", " + dialog->ui->oliney->text() + ")";
    QString ymaxpoint = "(" + dialog->ui->yline->text() + ", " + dialog->ui->olinex->text() + ")";

    paint.setPen(QPen(Qt::green));
    paint.setFont(QFont("Arial", 15, QFont::Bold));
          paint.drawText(Origin.x() + 8, Origin.y() + 18, originpoint);
          paint.drawText(Xmax.x() - 10, Xmax.y() - 8, xmaxpoint);
          paint.drawText(Ymax.x() + 8, Ymax.y() + 8, ymaxpoint);


    QPolygon poly1, poly2;

        poly1 << Xmax << QPoint(Xmax.x() - 12, Xmax.y() - 6)
             << QPoint(Xmax.x() - 12, Xmax.y() + 6)<< Xmax;

        poly2 << Ymax << QPoint(Ymax.x() + 6, Ymax.y() + 12) << QPoint(Ymax.x() - 6, Ymax.y() + 12) << Ymax;

        // style(), width(), brush(), capStyle() and joinStyle().
        QPen ArrowPen(Qt::magenta, 1);
        paint.setPen(ArrowPen);

        // Brush
        QBrush brush;
        brush.setColor(Qt::magenta);
        brush.setStyle(Qt::SolidPattern);

        // Fill polygon
        QPainterPath path1, path2;
        path1.addPolygon(poly1);
        path2.addPolygon(poly2);


        // Draw polygon
        paint.drawPolygon(poly1);
        paint.fillPath(path1, brush);
        paint.drawPolygon(poly2);
        paint.fillPath(path2, brush);

    imageLabel->setPixmap(pix);

}

Но моя программа падает. Я выяснил, где моя проблема, используя вывод сообщения "Привет!" С QDebug. Это в

pix = (*pixmap);

строка моего кода. Если я прокомментирую эту строку, программа не завершится сбоем, ничего не будет нарисовано. Декларация в .h файле:

const QPixmap* pixmap;
        QPixmap pix;
        const QPixmap * pixtemp;

Сообщение "Привет!" Пишется 2 раза, но 1 раз из 10 - 3 или 4 раза. Это смущает еще больше. Итак, проблема в том, как я рисую на этикетке (я полагаю). Есть ли более удобный или «правильный» способ рисования на этикетке, который не приведет к краху моей программы. Заранее спасибо!

1 Ответ

1 голос
/ 04 апреля 2019

Не пытайтесь рисовать в растровое изображение QLabel или манипулировать указателями. Вместо этого:

  1. Создание нового растрового изображения p в стеке (локальная переменная, без указателя) с использованием конструктора копирования
  2. Проверьте , правильно ли ваше растровое изображение (p.isNull())
  3. Рисовать на растровом изображении p
  4. Позвоните setPixmap(p) на свой ярлык

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

Примечание по рисованию в виджетах: если вы не хотите работать с копией, вы можете рисовать на виджете напрямую, создав и реализовав метод paint(). Кроме того, вы можете вызвать update() на виджете, чтобы вызвать перерисовку (которая вызовет ваш метод paint()). Это будет более эффективно, чем использование метки с растровым изображением.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...