如何使QGraphics每秒在R - G - B中闪烁背景



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

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

主窗口.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

**主窗口.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()
{}

主.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的这两个功能完全不熟悉,因此有点挣扎。

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

另外因为我正在处理一个QGraphicsView我觉得应该使用void paintEvent(QPaintEvent *) override

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

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

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

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

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

没有有趣的属性传递给QPropertyAnimation,因为不支持QPaletteQStringsetPalette()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

图形视图.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());
}

相关内容

  • 没有找到相关文章

最新更新