如何让QGraphicsView的背景在R - G - B中每秒闪烁一次?

问题描述 投票:0回答:1

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

下面是可验证的小例子。我写了最小的代码。

mainwindow.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()
{}

main.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,对此我并不熟悉。来源是 此处这个.

我从这些例子中得到的最重要的线索是,尤其是最后一个例子,使用了 QStateQStateMachine. 我对这两个特点完全不熟悉。Qt 不过,也因此而有些苦恼。

此外,我还遇到了 这个 局部的例子,好在我学会了如何设置。QTimer 对于1s的间隔闪烁很有用。

也因为我处理的是一个 QGraphicsView 我有这样的感觉 void paintEvent(QPaintEvent *) override 应该使用。

非常感谢你指出正确的方向并解决这个问题。

c++ qt c++11 qt5 qgraphicsview
1个回答
1
投票

使用 QPropertyAnimation 是一个问题,因为支持的类型列表是。

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

如果你看一下 QGraphicsView 阶层结构

QWidget 属性 QFrame 属性 QAbstractScrollArea 属性 QGraphicsView 属性

没有有趣的属性可以传给 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());
}
© www.soinside.com 2019 - 2024. All rights reserved.