如何使 QGraphicsView 背景每秒以 R-G-B 闪烁
How to make a QGraphicsView background blinking in R - G - B every second
正如标题所说,我正在尝试让我的 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
,对此我并不熟悉。来源是 and also .
我从这些例子中得到的最重要的线索是,特别是最后一个,使用了 QState
和 QStateMachine
。不过,我对 Qt
的这两个功能一点都不熟悉,因此我有点挣扎。
我还遇到了 this 部分示例,这样做的好处是我学会了如何设置 QTimer
对 1s 间隔闪烁有用。
也因为我处理的是QGraphicsView
,感觉应该用void paintEvent(QPaintEvent *) override
。
非常感谢您指出正确的方向并解决了这个问题。
这里使用QPropertyAnimation
是个问题,因为支持的类型列表是:
Int, UInt, Double, Float, QLine, QLineF, QPoint
QPointF, QSize, QSizeF, QRect, QRectF, QColor
如果您查看 QGraphicsView
class 层次结构的可用属性
QWidget
properties
QFrame
properties
QAbstractScrollArea
properties
QGraphicsView
properties
没有有趣的属性传递给 QPropertyAnimation
因为 QPalette
和 QString
不支持与 setPalette()
和 styleSheet()
一起玩没有变量可以直接改变背景颜色
一个解决办法是subclass 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());
}
正如标题所说,我正在尝试让我的 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
,对此我并不熟悉。来源是
我从这些例子中得到的最重要的线索是,特别是最后一个,使用了 QState
和 QStateMachine
。不过,我对 Qt
的这两个功能一点都不熟悉,因此我有点挣扎。
我还遇到了 this 部分示例,这样做的好处是我学会了如何设置 QTimer
对 1s 间隔闪烁有用。
也因为我处理的是QGraphicsView
,感觉应该用void paintEvent(QPaintEvent *) override
。
非常感谢您指出正确的方向并解决了这个问题。
这里使用QPropertyAnimation
是个问题,因为支持的类型列表是:
Int, UInt, Double, Float, QLine, QLineF, QPoint
QPointF, QSize, QSizeF, QRect, QRectF, QColor
如果您查看 QGraphicsView
class 层次结构的可用属性
QWidget
properties
QFrame
properties
QAbstractScrollArea
properties
QGraphicsView
properties
没有有趣的属性传递给 QPropertyAnimation
因为 QPalette
和 QString
不支持与 setPalette()
和 styleSheet()
一起玩没有变量可以直接改变背景颜色
一个解决办法是subclass 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());
}