1
votes

Hi I've got a GridLayout which has 64 GraphicsViews on it (I know it's alot but it's the only way i could think of doing this at this point in time). Now i'm currently just drawing a random line on each of these graphics views on a timer tick. This works but only for the 8 of the Graphics, Create Graphics Views
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);
        }

    }
}

Random Line in each graphics view

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;
}

show updated graphics view

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

I've looked through it for the last 2 hours trying multiple approaches none of which have fixed this problem, I'm assuming it's probably something stupid but I just can't figure it out

Any help is greatly appreciated Thank you

Also if i try to update any of the Graphics Views other than the ones which work they still don't update.

https://gist.github.com/gazza126/f43d5b0377649782a35d -- Full Code (that does anything)

1
There's no need to "show" the updated views, the whole point of them is so that they update automatically whenever the underlying scene is modified. You'll need to post a complete, self contained, single-file example of what you're trying to do. For inspiration, look at github.com/KubaO/stackoverflown/blob/master/…Kuba hasn't forgotten Monica
okay thought the show might have been needed, or atleast a repaint (last c++ gui i did was C++ .NET) gist.github.com/gazza126/f43d5b0377649782a35d Theres the whole .cpp and header file, I've only put simulation in as the other bit atm is just a start menu. Atm it is just drawing a random line in each Graphics view, really as a test, then i will be adding the logic behind the actual simulationgjones
Your code must be included in the question itself, and you must minimize it. Your problem so far is that you are running a local event loop. Never do that without full understanding of how Qt's internals work.Kuba hasn't forgotten Monica
Just to clarify, even if i try to draw a line in the graphicsViews which aren't working outside of the event loop (so by completely commenting out the loop) the line still won't drawgjones

1 Answers

1
votes

The below works. Make sure that you enable C++11 in your .pro file: add CONFIG += c++11 to the project file.

#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();
}