Как заставить фон QGraphicsView мигать в R - G - B каждую секунду - PullRequest
0 голосов
/ 30 апреля 2020

Как видно из названия, я пытаюсь, чтобы мой QGraphicsView мигал 1 секунду красным, 1 секунду зеленым и 1 секунду синим, после чего l oop начинается снова. После многих исследований, проведенных за последние пару дней, мне не повезло, так как основная проблема заключается в том, что я не уверен, что мне нужен подкласс 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();
}

In Если вы хотели бы увидеть .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 вторая синяя и после этого l oop начинается заново.

Единственный источник, который мне удалось найти, предоставив полный пример, был в PyQt, с которым я не знаком. Источник здесь , а также этот .

Наиболее важный ключ, который я получил из этих примеров, заключается в том, что, в частности, последний использует QState и QStateMachine. Я совсем не знаком с этими двумя особенностями Qt, хотя из-за этого немного борюсь.

Также я натолкнулся на этот частичный пример и хорошую вещь это то, что я узнал, как установить QTimer, полезный для мигания интервала 1 с.

Кроме того, поскольку я имею дело с QGraphicsView, у меня есть ощущение, что следует использовать void paintEvent(QPaintEvent *) override.

Большое спасибо за указание в правильном направлении и решение этой проблемы.

1 Ответ

1 голос
/ 02 мая 2020

Использование QPropertyAnimation является проблемой здесь, потому что список поддерживаемых типов:

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

И если вы посмотрите доступные свойства иерархии классов QGraphicsView

QWidget свойства
QFrame свойства
QAbstractScrollArea свойства
QGraphicsView свойства

Нет интересных свойств для передачи на QPropertyAnimation, потому что QPalette и QString не поддерживаются для игры с 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());
}
...