【问题标题】:Change circle colour every 5 seconds每 5 秒更改一次圆圈颜色
【发布时间】:2020-11-05 00:03:00
【问题描述】:

我尝试创建一个每 5 秒消失的绿色圆圈。

实际上,我使用QPainter 方法创建了绿色圆圈。我尝试了QTimer 和其他方法,但我找不到好的解决方案。

我这样重写了paintEvent函数:

void MainWindow::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    Qt::BrushStyle style = Qt::SolidPattern;
    QBrush brush(Qt::green, style);
    painter.setRenderHint(QPainter::Antialiasing);
    painter.setBrush(brush);
    painter.drawEllipse(525, 5, 50, 50);
}
MainWindow::MainWindow() : QWidget()
{
    QTimer *ledtimer = new QTimer(this);
    connect(ledtimer, SIGNAL(timeout()), this, SLOT(run_led()));
    ledtimer->start(5000);
}

我试图做这样的事情,但是当我使用 run_led 时,它告诉我 Painter 已被删除(我在 MainWindow 类中尝试过)。

我了解信号功能和计时器,我在其他文件中使用过它,因此不胜感激。我应该使用计时器让圆圈眨眼吗?

【问题讨论】:

  • run_led 在哪里?
  • 这是一个没用的函数,只是为了测试。我复制粘贴与paintEvent相同的代码
  • 问题是MainWindow::paintEvent!你不应该对QMainWindow的子类这样做!
  • 我应该把它分开吗?
  • 如果run_led 是一个无用的函数,那么示例中的定时器在做什么,因为它从不用于有用的事情。您可能想定期调用update 并切换窗口的状态(绿色圆圈可见/隐藏)。

标签: c++ qt qt5 qpainter


【解决方案1】:
class QSimpleLed : public QWidget
{
   Q_OBJECT
   Q_PROPERTY(QColor color READ color WRITE setColor)
public:
   using QWidget::QWidget;

   void setColor(const QColor& c) {
      if (m_color != m) {
          m_color = m;
          update();
      } 
   }

   QColor color() const;

   void paintEvent(QPaintEvent *) override;

private:
   QColor m_color;
}

上面的实现应该是显而易见的。

int main(int argc, char* argv[])
{
    QApplication app{argc, argv};

    QSimpleLed led;
    auto animation = new QPropertyAnimation(&led, "color");
    animation->setStartValue(Qt::red);
    animation->setEndValue(Qt::green);
    animation->setLoopCount(-1);
    animation->setDuration(5000);
    animation->start();

    led.show();
    return app.exec();
}

【讨论】:

【解决方案2】:

假设你的 MainWindowinherits QMainWindow


MainWindow::paintEvent(QPaintEvent *) 是一个告诉系统渲染窗口的函数。 所以我让你猜猜当你这样覆盖它时出了什么问题。

但是您可以将绘图放在为此制作的QWidget 中:QGraphicsView 显示QGraphicsScene 的内容。

你应该创建一个slot 来做你想做的事,像这样:

void MainWindow::on_led_timer_timeout(){

/*
 Do stuff the the QGraphicsScene or QGraphicsView
*/

}

然后将您的QTimer 的正确signal 连接到它:

connect(ledtimer, &QTimer::timeout, this, &MainWindow::on_led_timer_timeout);

【讨论】:

    【解决方案3】:

    定义一个每 5 秒更改一次的标志布尔值,并在绘画中使用画笔作为全局变量

    void MainWindow::paintEvent(QPaintEvent *)
    {
        ....
        QBrush brush(myBrush, style);
        ...
    }
    
    and in slot (run_led)
    
    void MainWindow::run_led()
    {
        c != true;
        if(c)
        {
            myBrush=Qt::green;
        }
        else
        {
            myBrush=Qt::gray;
        }
    }
    

    【讨论】:

    • “c”是什么意思?
    • 我刚试过你的例子。布尔值也在改变值和颜色,但不是圆圈。看起来该函数没有执行paintevent函数...
    • 这个例子是有效的,你必须调用更新函数来使它修改窗口。像这样:connect(ledtimer, SIGNAL(timeout()), this, SLOT(run_led())); connect(ledtimer, SIGNAL(timeout()), this, SLOT(update()));
    猜你喜欢
    • 1970-01-01
    • 2013-05-27
    • 1970-01-01
    • 2022-11-10
    • 2012-06-27
    • 2011-09-25
    • 2013-12-19
    • 1970-01-01
    • 2013-04-25
    相关资源
    最近更新 更多