QGraphicsView не всегда обновляется

Привет, у меня есть GridLayout, в котором есть 64 GraphicsViews (я знаю, что это много, но это единственный способ, которым я мог бы это сделать на данный момент). Теперь я просто рисую случайную линию в каждом из этих графических представлений по таймеру. Это работает, но только для 8 видов графики, создания графических представлений
void Simulation::createGraphicsViews(){ for(int i = 0; i ‹ 64; i++){ for(int j = 0; j ‹ 8; j++){

        graphicsScene[i] = new QGraphicsScene();
        graphicsView[i] = new QGraphicsView(graphicsScene[i]);
        simui->gridLayout->addWidget(graphicsView[i], i/8, j);
        }

    }
}

Случайная линия в каждом графическом представлении

for(int x = 0; x < 64; x++){
    x1 = qrand()%(50+1) - 1;
    y1 = qrand()%(50+1)-1;
    x2 = qrand()%(50+1)-1;
    y2 = qrand()%(50+1)-1;
    graphicsScene[x]->addLine(x1,y1,x2,y2);
    qDebug() << "adding line to" << x << "at" << x1 <<","<<y1<<","<<x2<<","<<y2;
}

показать обновленный графический вид

 for(int x = 0; x < 64; x++){
        graphicsView[x]->show();
        qDebug()<<"showing" << x;
  }

Я просматривал его последние 2 часа, пробуя несколько подходов, ни один из которых не решил эту проблему, я предполагаю, что это, вероятно, что-то глупое, но я просто не могу понять это.

Любая помощь очень ценится Спасибо

Кроме того, если я попытаюсь обновить любое из графических представлений, кроме тех, которые работают, они все равно не обновятся.

https://gist.github.com/gazza126/f43d5b0377649782a35d — полный код (который делает все )


person gjones    schedule 25.02.2015    source источник
comment
Нет необходимости показывать обновленные виды, весь их смысл в том, что они автоматически обновляются всякий раз, когда изменяется основная сцена. Вам нужно опубликовать полный, автономный, однофайловый пример того, что вы пытаетесь сделать. Для вдохновения посмотрите github.com/KubaO/stackoverflown. /блоб/мастер/   -  person Kuba hasn't forgotten Monica    schedule 25.02.2015
comment
хорошо, подумал, что может понадобиться шоу или, по крайней мере, перерисовка (последний графический интерфейс С++, который я сделал, был C++ .NET) gist.github.com/gazza126/f43d5b0377649782a35d Там есть весь .cpp и заголовочный файл, я добавил только симуляцию, так как другой бит atm — это просто меню «Пуск». Atm, это просто рисование случайной линии в каждом графическом представлении, на самом деле в качестве теста, затем я добавлю логику, лежащую в основе фактического моделирования.   -  person gjones    schedule 25.02.2015
comment
Ваш код должен быть включен в сам вопрос, и вы должны минимизировать его. Ваша проблема до сих пор заключается в том, что вы используете локальный цикл событий. Никогда не делайте этого без полного понимания того, как работает Qt.   -  person Kuba hasn't forgotten Monica    schedule 25.02.2015
comment
Просто чтобы уточнить, даже если я попытаюсь нарисовать линию в GraphicsViews, которые не работают вне цикла событий (поэтому, полностью закомментировав цикл), линия все равно не будет отображаться   -  person gjones    schedule 25.02.2015


Ответы (1)


Ниже работает. Убедитесь, что вы включили C++11 в файле .pro: добавьте CONFIG += c++11 в файл проекта.

#include <QApplication>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QGraphicsLineItem>
#include <QGridLayout>
#include <QTime>
#include <QTimer>
#include <array>

class View : public QGraphicsView
{
public:
   View(QWidget *parent = 0) : QGraphicsView(parent) {
      setRenderHint(QPainter::Antialiasing);
   }
   void resizeEvent(QResizeEvent *) {
      fitInView(-1, -1, 2, 2, Qt::KeepAspectRatio);
   }
};

template <typename Container>
void updateScenes(Container & views)
{
   auto angle = 360.0/1000.0 * (QTime::currentTime().msecsSinceStartOfDay() % 1000);
   for (auto & view : views) {
      auto scene = view.scene();
      scene->clear();
      auto * line = scene->addLine(-1, 0, 1, 0, QPen(Qt::darkBlue, 0.1));
      line->setRotation(angle);
   }
}

int main(int argc, char *argv[])
{
   QApplication a(argc, argv);
   QGraphicsScene s;
   QTimer timer;
   QWidget window;
   QGridLayout layout(&window);
   std::array<View, 64> views;

   int i = 0;
   for (auto & view : views) {
      view.setScene(new QGraphicsScene(&view));
      layout.addWidget(&view, i/8, i%8);
      ++ i;
   }

   QObject::connect(&timer, &QTimer::timeout, [&views]{ updateScenes(views); });
   timer.start(50);
   window.show();
   return a.exec();
}
person Kuba hasn't forgotten Monica    schedule 25.02.2015
comment
Большое спасибо, я только что проверил это в отдельной программе и отлично работает. Переделаю остальную часть моего кода, чтобы связать что-то похожее на это. Спасибо :) - person gjones; 26.02.2015