【问题标题】:How to make a QGraphicsView background blinking in R - G - B every second如何使 QGraphicsView 背景以 R - G - B 每秒闪烁
【发布时间】:2020-08-15 08:16:58
【问题描述】:

正如标题所说,我试图让我的QGraphicsView 以红色闪烁 1 秒、以绿色闪烁 1 秒、以蓝色闪烁 1 秒,然后循环重新开始。在过去几天做了很多研究之后,我没有很多运气,因为主要问题是我不确定我是否需要继承 QGraphicsView 才能获得我想要的效果。我遇到了一些我在下面插入的参考资料,说对于这类问题QPropertyAnimation 似乎是正确的方向。虽然设置QTimer 也是一种选择。

在可验证的小示例下方。我写了最少的代码:

ma​​inwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QGraphicsView>
#include <QGraphicsScene>
#include <QPropertyAnimation>

QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private:
    Ui::MainWindow *ui;
    QGraphicsView *mView;
    QGraphicsScene *mScene;
    QPropertyAnimation *mAnimation;
};
#endif // MAINWINDOW_H

**mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QTimer>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    mView = new QGraphicsView();
    mScene = new QGraphicsScene();
    ui->graphicsView->setScene(mScene);
    // Starting with a gray background
    ui->graphicsView->setBackgroundBrush(QColor(Qt::gray));

    // Setting a timer that changes the color every second
    QTimer *timer = new QTimer(this);
    connect(timer, SIGNAL(timeout()), this, SLOT(update()));
    timer->start(1000);

}

MainWindow::~MainWindow()
{
    delete ui;
}

mygraphicsview.h

#ifndef MYGRAPHICSVIEW_H
#define MYGRAPHICSVIEW_H
#include <QGraphicsView>
class MyGraphicsView : public QGraphicsView
{
public:
    MyGraphicsView();
};

#endif // MYGRAPHICSVIEW_H

**mygraphicsview.cpp

#include "mygraphicsview.h"

MyGraphicsView::MyGraphicsView()
{}

ma​​in.cpp

#include "mainwindow.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    return a.exec();
}

如果你想看.ui我也分享这个文件:

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>MainWindow</class>
 <widget class="QMainWindow" name="MainWindow">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>277</width>
    <height>228</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>MainWindow</string>
  </property>
  <widget class="QWidget" name="centralwidget">
   <layout class="QGridLayout" name="gridLayout">
    <item row="0" column="0">
     <widget class="QGraphicsView" name="graphicsView"/>
    </item>
   </layout>
  </widget>
  <widget class="QMenuBar" name="menubar">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>277</width>
     <height>22</height>
    </rect>
   </property>
  </widget>
  <widget class="QStatusBar" name="statusbar"/>
 </widget>
 <resources/>
 <connections/>
</ui>

我一直在研究让QGraphicsView 以红色闪烁 1 秒、以绿色闪烁 1 秒、以蓝色闪烁 1 秒的可能性,然后循环重新开始。

我能找到提供完整示例的唯一来源是PyQt,对此我并不熟悉。来源是herethis one

我从这些例子中得到的最重要的线索是,特别是最后一个,使用了QStateQStateMachine。不过,我对Qt 的这两个功能完全不熟悉,因此我有点挣扎。

我还遇到了this 的部分示例,这样做的好处是我学会了如何设置QTimer 对1s 间隔闪烁有用。

还因为我正在处理QGraphicsView,所以我觉得应该使用void paintEvent(QPaintEvent *) override

非常感谢您指出正确的方向并解决此问题。

【问题讨论】:

  • QPropertyAnimation 不是一个糟糕的解决方案,但在这种情况下您不能使用它,因为没有允许直接更改背景颜色的property,您可以使用 QPalette 但它没有t 与QPropertyAnimation 一起工作,一个可能的解决方案确实是重新实现paintEvent(),但有很多解决方案......使用QGraphicsScene,使用QGraphicsView 等......

标签: c++ qt c++11 qt5 qgraphicsview


【解决方案1】:

这里使用QPropertyAnimation是个问题,因为支持的类型列表是:

Int, UInt, Double, Float, QLine, QLineF, QPoint
QPointF, QSize, QSizeF, QRect, QRectF, QColor

如果您查看 QGraphicsView 类层次结构的可用属性

QWidgetproperties
QFrameproperties
QAbstractScrollAreaproperties
QGraphicsViewproperties

没有有趣的属性可以传递给QPropertyAnimation,因为QPaletteQString 不支持与setPalette()styleSheet() 一起使用,并且没有变量可以直接更改背景颜色。


一个解决方案是继承QGraphicsView:
graphicsview.h:

#ifndef GRAPHICSVIEW_H
#define GRAPHICSVIEW_H

#include <QGraphicsView>
#include <QTimer>

class GraphicsView : public QGraphicsView
{
    Q_OBJECT
public:
    GraphicsView(QWidget *parent = nullptr);

protected:
    void paintEvent(QPaintEvent *evt) override;

private slots:
    void changeBackgroundColor();

private:
    int color_index;
    QTimer timer;
    const QColor colors[3] = { Qt::red, Qt::green, Qt::blue };

};

#endif // GRAPHICSVIEW_H

graphicsview.cpp

#include "graphicsview.h"

GraphicsView::GraphicsView(QWidget *parent)
    : QGraphicsView(parent)
{
    color_index = -1;
    connect(&timer, SIGNAL(timeout()), this, SLOT(changeBackgroundColor()));
    timer.start(1000);
}

void GraphicsView::paintEvent(QPaintEvent *evt)
{
    QGraphicsView::paintEvent(evt);

    QPainter painter(viewport());
    painter.fillRect(viewport()->rect(), colors[color_index]);
}

void GraphicsView::changeBackgroundColor()
{
    if (color_index == 2){
        color_index = 0;
    } else {
        color_index++;
    }
    viewport()->update(rect());
}

【讨论】:

  • 非常感谢您非常详细的解释。我应用了你的建议,它完全符合我的要求。我也明白你为什么提到QPropertyAnmation 限制。谢谢你的时间!非常感谢!! :)
猜你喜欢
  • 2012-06-19
  • 1970-01-01
  • 2010-09-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-19
  • 2013-04-17
  • 1970-01-01
相关资源
最近更新 更多