2

I'm using QtCreator to build an interface application.

I'm just getting used to Qt and toying around trying to draw stuff on a QtGraphicsView.

Since I created my interface with the editor, I am retrieving my objects in the code like so (please tell me if this is wrong).

this->m_graphView = this->findChild<QGraphicsView *>("graphicsView");
this->m_graphScene = this->m_graphView->scene();

I have buttons on the interface and already created slots to react to the clicked event.

I'm just trying to draw something (anything) on the graphics view that is on my MainWindow (geometry : [(10,10), 320x240]).

I've been reading examples online and I can't make anything work.

My current code is as follows :

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    this->m_graphView = this->findChild<QGraphicsView *>("graphicsView");
    this->m_graphScene = this->m_graphView->scene();
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_btnDown_clicked()
{
    qDebug() << "STUB : button DOWN";

    m_graphScene->addLine(0, 0, 42, 42, QPen(QBrush(Qt::black),1));
    m_graphView->show();
}

void MainWindow::on_btnLeft_clicked()
{
    qDebug() << "STUB : button LEFT";
}

void MainWindow::on_btnUp_clicked()
{
    qDebug() << "STUB : button UP";
}

void MainWindow::on_btnRight_clicked()
{
    qDebug() << "STUB : button RIGHT";
}

void MainWindow::on_btnShoot_clicked()
{
    qDebug() << "STUB : button SHOOT";
}

But annoyingly, it doesn't draw anything and I even get this error when the addLine method is called

QGraphicsScene::addItem: item has already been added to this scene

What's wrong in my code and/or my ways of doing things? I just want to draw something but can't make it, thank you.

dominicbri7
  • 2,479
  • 4
  • 23
  • 33

1 Answers1

4

retrieving widget in form

you can get graphicsView pointer (and its scene) more easier.
"ui" member has the pointer to widgets arranged in .form file.
(If you please, see "ui_mainwindow.h" file)

// assign to pointer
QGraphicsView *view = ui->graphicsView;
view->...

// or directly (I like this)
ui->graphicsView->...

so, Mainwindow class don't need "m_graphicsView" member.

graphics view

QGraphicsView need to set scene.(It has no scene at first)
We have to create QGraphicsScene ourselves.
So Mainwindow class need "m_graphicsScene" member.

m_graphicsScene = new QGraphicsScene(this);
ui->graphicsView->setScene(m_graphicsScene);

drawing more easier

If you just want to draw something, you can override "paintEvent" method.
PaintEvent is QWidget's virtual method.

in .h file:

protected:
    void paintEvent(QPaintEvent *event);

in .cpp file:

void MainWindow::paintEvent(QPaintEvent *event)
{
    // unuse
    Q_UNUSED(event);

    // pass "this" pointer to painter
    QPainter painter(this); 

    // setPen
    // QPen can take "Qt::black" directly as first arg (without QBrush() constructor)
    painter.setPen(QPen(Qt::black), 1);

    // draw line
    painter.drawLine(0, 0, 42, 42);
}

please enjoy Qt!

Taurano
  • 41
  • 1
  • thank you, you've been very helpful, but I've noticed a few things. First the paintEvent method doesn't draw on the graphicsview but the mainwindow itself (i don't want anything to be drawn outside the graphics view). – dominicbri7 Feb 22 '15 at 06:48
  • Secondly what will be drawn will change (My mainwindow has a model that tracks the x and y position which will change over time, that's what the button (up right down left) are for. Currently, in the buttons slots I change the x,y values of my model, and I call this->repaint, is this a good practice? – dominicbri7 Feb 22 '15 at 06:59