Qt GRaphic

Verschiedenes zu Qt
Antworten
rennreh
Beiträge: 4
Registriert: 2. April 2013 17:28

Qt GRaphic

Beitrag von rennreh »

Hallo,

Ich bin gerade dabei Qt zuerlernen. Ich wollte in einem QGraphicView den zustand eines unsortierten Vectors(int) visualisieren und während der sortierung anschauen.
so wie in diesem video: http://www.youtube.com/watch?v=lyHB5kimryQ
Nur anders als im video möchte ich den Farbton entsprechend der Wertigkeit ändern.

Ich habe mit QT-Creator ein QGraphicView angelegt und beim click auf dem button soll eine zahlenarray sortiert werden, zuvor gebe ich es im graphicview aus:

Code: Alles auswählen

// der konstruktor
MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent), ui(new Ui::MainWindow)
{
    ui->setupUi(this);

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

    for(int i=0;i<256;i++) {
        values[i] = irand(0,8096);
        QPen blackPen(QColor(255*values[i]/8096,0,0,255));
        blackPen.setWidth(1);
        line[i] = scene->addLine(i,0,i,50,blackPen);

    }

    connect(ui->pushButton,SIGNAL(clicked()),this,SLOT(bubbleSort()));
}

Code: Alles auswählen

// der slot
void MainWindow::bubbleSort() {
    int tmp;
    QPen*pen;

    for(int i=0; i<256; i++) {
        for(int j=0; j<256; j++) {
            if(values[i]<values[j]) {
                tmp = values[i];
                values[i]=values[j];
                values[j]=tmp;
            }
        }
    }

    for(int i=0; i<256; i++) {
        QPen blackPen(QColor(0,255*values[i]/8096,0,255));
        blackPen.setWidth(1);
        line[i] = scene->addLine(i,0,i,50,blackPen);
    }
}
Entweder verstehe ich das mit der scene falsch oder .. mit dem addLine füge ich doch ein neues Element in die scene ein oder? Wie kann ich zugriff auf die bereits erstellten elemente erhalten, damit ich dessen eigenschafften wie farbton und position manipulieren kann?

Mit besten Gruß
rennreh
Beiträge: 4
Registriert: 2. April 2013 17:28

Re: Qt GRaphic

Beitrag von rennreh »

oki, ich hab mein Problem selbst gelöst :)

Code: Alles auswählen

#ifndef MAINWINDOW_H
#define MAINWINDOW_H


#include <QGraphicsTextItem>
#include <QGraphicsScene>
#include <QMainWindow>
#include <QMouseEvent>
#include <QPainter>
#include <QTimer>
#include <QWidget>
#include <QEvent>
#include <QLine>
#include <QTime>

#define CONST_ITEMS 64
#define CONST_PEN_WIDTH 5

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT
    
public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

private:
    int values[CONST_ITEMS];
    QGraphicsLineItem*qline[CONST_ITEMS];

    Ui::MainWindow*ui;
    QGraphicsScene*scene;
    QTimer*qtim;

    int irand(int a,int e);
    void delay();

    private slots:
    void bubbleSort();
};

#endif // MAINWINDOW_H

Code: Alles auswählen

#include "mainwindow.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    
    return a.exec();
}

Code: Alles auswählen

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent), ui(new Ui::MainWindow)
{
    ui->setupUi(this);

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

    for(int i=0;i<CONST_ITEMS;i++) {

        values[i] = irand(0,131072);
        QPen pen(QColor(255*values[i]/131072,0,0,255));
        pen.setWidth(1+CONST_PEN_WIDTH);
        qline[i] = new QGraphicsLineItem(i*CONST_PEN_WIDTH,0,i*CONST_PEN_WIDTH,50);
        qline[i]->setPen(pen);
        scene->addItem(qline[i]);
    }

    connect(ui->pushButton,SIGNAL(clicked()),this,SLOT(bubbleSort()));
}


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

void MainWindow::bubbleSort() {
    QPen pen;
    int tmp;

    pen.setWidth(1+CONST_PEN_WIDTH);

    for(int i=0; i<CONST_ITEMS; i++) {
        for(int j=0; j<CONST_ITEMS; j++) {
            if(values[i]<values[j]) {
                tmp = values[i];
                values[i]=values[j];
                values[j]=tmp;

                if(!(j%1))
                    delay();

            }
            pen.setColor(QColor(0,255*values[j]/131072,0,255));
            qline[j]->setPen(pen);
        }
    }
}


int MainWindow::irand(int a, int e) {
    double r = e - a + 1;
    return a + (int)(r * qrand()/(RAND_MAX+1.0));
}

void MainWindow::delay()
{
    QTime dieTime= QTime::currentTime().addMSecs(1);
    while( QTime::currentTime() < dieTime )
    QCoreApplication::processEvents(QEventLoop::AllEvents, 100);
}
veeman
Beiträge: 277
Registriert: 3. Oktober 2012 01:43
Kontaktdaten:

Re: Qt GRaphic

Beitrag von veeman »

Was ist bei dir line? Ja, addLine fügt jedes mal eine neue Linie hinzu.
Du könntest auch einfach scene->clear() verwenden und die Linien jedes mal neu erstellen.
Ansonsten kannst du per line auf die erstellten Elemente zugreifen.

Beachte das du dein Array so wie es momentan ist komplett sortiert wird und erst nach dem Sortieren angezeigt werden.
Wenn du es visualisieren möchtest solltest du 1. deine Sortierschleife auseinander nehmen und 2. das ganze in einem Timer verbauen
und nur schrittweiße durchgehen um die einzelnen Schritte darstellen zu können.

//Edit: Ok konntest es selbert lösen, solange es nur zur Demozwecken fungiert sollte deine Lösung ausreichen.
Ansonsten sollte die Verwendung von QCoreApplication::processEvents(); vermieden werden.
rennreh
Beiträge: 4
Registriert: 2. April 2013 17:28

Re: Qt GRaphic

Beitrag von rennreh »

Danke veeman für dein feedback.

//Edit: Ok konntest es selbert lösen, solange es nur zur Demozwecken fungiert sollte deine Lösung ausreichen.
Ansonsten sollte die Verwendung von QCoreApplication::processEvents(); vermieden werden.

Das finde ich ja Interessant. Wieso was ist daran so schlimm? Also ich suchte schnell nach einer Möglichkeit um "blockierungsfrei" zu warten. Also Im prinzip ein timer der im hintergrund solange den prozessor wieder freigibt bis der timer eben abgelaufen ist, also im prinzip:

Code: Alles auswählen

while(tim.isNottimeout())
    sched();
Wie sollte ich denn den Timer am besten realisieren?

Mit besten Grüßen
Antworten