如何在每次 QTimer 发射时使用 QLabel

Posted

技术标签:

【中文标题】如何在每次 QTimer 发射时使用 QLabel【英文标题】:How to draw on QLabel with every QTimer emission 【发布时间】:2019-04-04 13:49:59 【问题描述】:

我的目标是在每次 QTimer 发射时都使用 QLabel。 以下是我试图实现这一目标的方法:

所以,计时器是通过触发一个动作来创建的。 我希望在每次计时器发射时绘制度量,其参数随着用户向对话框输入数据而更新。

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 的“Hey there”消息输出找出了我的问题所在。它在

pix = (*pixmap);

我的代码行。如果我评论此行程序不会崩溃,则也不会绘制任何内容。 .h 文件中的声明:

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

“Hey there”消息大部分时间被写入 2 次,但在 10 次中有 1 次被写入 3 或 4 次。这更令人困惑。 所以,问题是我如何在标签上画画(我想)。有没有更方便或“正确”的方式来绘制标签,这不会导致我的程序崩溃。 提前致谢!

【问题讨论】:

【参考方案1】:

不要尝试在 QLabel 的像素图中绘制或使用指针进行修改。而是:

    使用copy constructor 在堆栈(局部变量,无指针)上创建一个新的像素图p 检查您的像素图是否有效 (p.isNull()) 在像素图上绘制p 在您的标签上致电setPixmap(p)

关于 Qt 属性的一般说明:Qt 属性不能直接修改。对 Qt 属性的访问总是通过获取和设置来实现的。所以,如果你想操作一个属性,你用getter初始化一个局部变量,然后修改你的局部变量,然后使用setter。

关于绘制到小部件的说明:如果您不想处理副本,可以通过派生和实现paint() 方法直接在小部件上绘制。此外,您可以在小部件上调用update() 来触发重绘(这将调用您的paint() 方法)。这将比使用带有像素图的标签更有效。

【讨论】:

我将您的建议应用于我的代码。现在我的程序不会崩溃并按预期工作。谢谢!

以上是关于如何在每次 QTimer 发射时使用 QLabel的主要内容,如果未能解决你的问题,请参考以下文章

QT 如何实现记录运行时间

定时器QTimer

Pyqt5:使用Qlabel标签进行视频播放

QTimer 不触发(触发)超时

在 QTimer Singleshot 之后终止 QThread

qt中在QLabel中显示动态图片??