paintEvent(QPaintEvent *event) überladen

Alles rund um die Programmierung mit Qt
Antworten
Marcus Breuer
Beiträge: 113
Registriert: 31. März 2011 17:19
Wohnort: Aachen
Kontaktdaten:

paintEvent(QPaintEvent *event) überladen

Beitrag von Marcus Breuer »

hallo programmierer,

ich bin sowohl neu in dem forum als auch erst neuerdings mit qt "bekannt"
ich bin leider nicht mit dem talent gesegnet, wirklich gut programmieren zu können. ich muss allerdings für ein praktikum an einer hochschule eine technische anwendung schreiben.

ich muss einen graphen und eine funktion ausgeben können. ich habe daher eine klasse graph von qwidget abgeleitet und dieser die methode paintEvent(...) mitgegeben. erste linien zu zeichen klappte wunderbar.
nun bekomme ich allerdings die daten bzw. funktionswerte für die funktion aus einer anderen klasse. (die bearbeite ich leider nicht, daher weiß ich auch noch nicht, wie sie aussieht)

meine frage ist nur, wie kann ich die funktion paintEvent(QPaintEvent *event) so überladen, dass ich ihr quasi noch ein paar int-werte mitgebe und diese dann auf dem gleichen widget wie der graph gezeichnet werden?
hatte schon probiert einfach die argumentliste zu erweitern. das wollte aber nicht so recht.

bitte um eure hilfe und bin dankbar für jede antwort.

grüße,
marcus

mein code der klasse graph: (nichts berauschendes)

Code: Alles auswählen

//graph.h
#ifndef GRAPH_H
#define GRAPH_H

#include<QWidget>

class graph : public QWidget{

Q_OBJECT

public:
    graph(QWidget *parent = 0);


protected:
    void paintEvent(QPaintEvent *event);
};

#endif // GRAPH_H

Code: Alles auswählen

//graph.cpp
#include "graph.h"
#include<QPainter>

graph::graph(QWidget *parent) : QWidget(parent) {}

void graph::paintEvent(QPaintEvent *event) {
    QPainter achsen(this);
    achsen.setPen(QPen(Qt::black, 1));
    achsen.begin(this);
    achsen.drawLine(0, 350, 500, 350);
    achsen.drawLine(0, 0, 0, 350);

    for(int x = 25; x < 500; x += 25) {
        achsen.drawLine(x, 350, x, 345);

    };

    for(int y = 25; y < 350; y += 25) {
        achsen.drawLine(0, y, 5, y);
    };
    achsen.end();
}
// edit franzf: Code-Tags hinzugefügt, bitte in Zukunft selber machen, Danke :)
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Re: paintEvent(QPaintEvent *event) überladen

Beitrag von franzf »

Marcus Breuer hat geschrieben:hatte schon probiert einfach die argumentliste zu erweitern. das wollte aber nicht so recht.
Weil C++ das nicht gestattet - das ist dann eine ganz andere Funktion.

Das paintEvent() ist DIE Methode, die aufgerufen wird, wenn das Widget (oder Teile davon -> QPaintEvent::rect()) neu gezeichnet werden soll. Wenn du also Punkte zeichnen willst, die man dem Widget mitteilen können soll, musst du das in einer eigenen Methode machen, das Widget speichert dann diese Werte, das Neuzeichnen wird mit update() angestoßen.
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

Wie wäre es mit qwt. Alles andere ist m.E. (auch in Anbetracht der Vorkenntnisse) nicht wirklich zu empfehlen.
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
padreigh
Beiträge: 340
Registriert: 13. Mai 2010 10:06

Beitrag von padreigh »

Versuch mal lieber das hier: http://qwt.sourceforge.net/
Patrick (QtCreator 1.3.1, Qt 4.6.3)
---
template = subdirs
Marcus Breuer
Beiträge: 113
Registriert: 31. März 2011 17:19
Wohnort: Aachen
Kontaktdaten:

Beitrag von Marcus Breuer »

vielen dank für eure schnellen antworten.

@franzf: heißt das, ich kann keinen QPainter mehr laden, wenn ich an paintEvent(...) irgendwas versuche würde zu ändern?
--------
es tut mir leid, ich bin wahrliche kein fachmann auf diesem gebiet. bin eigentlich aus dem bereich maschinenbau.
--------
@Christian81 und padreigh: von qwt wollte ich eigentlich die finger lassen. ich habe probiert das zu installieren, bin aber auch dabei kläglich gescheitert.
ich hatte auch uwe rathmann schon geschrieben, bekam aber eine weniger hilfreiche antwort, nachdem ich einen ganzen tag lang nach lösungen gegoogelt hatte.
--------
ich will mir hier keine komplettlösung zu meinem problem erschleichen, aber welchen ansatz muss ich in etwa wählen, so dass ich die funktion in das selbe widget zeichnet und zusätzlich die entsrechenden werte übergeben bekommt? das nervt mich gerade selbst, denn alles, was ich weiß ist, dass es gerade mal um zwei wertepaare geht. aber die muss ich übergeben bekommen und dann "in den graphen" zeichnen.

danke nochmals
Marcus Breuer
Beiträge: 113
Registriert: 31. März 2011 17:19
Wohnort: Aachen
Kontaktdaten:

Beitrag von Marcus Breuer »

@franzf: beim nächsten mal mit code tags:) entschuldige
Marcus Breuer
Beiträge: 113
Registriert: 31. März 2011 17:19
Wohnort: Aachen
Kontaktdaten:

Beitrag von Marcus Breuer »

und nochmal ich. ich denke, ich habe die oberste antwort von franzf jetzt verstanden. ich werde mich weiter dransetzen und ggfs. einfach nochmal code posten. aber denke, dass das in etwa auch für mich verständlich war.
Marcus Breuer
Beiträge: 113
Registriert: 31. März 2011 17:19
Wohnort: Aachen
Kontaktdaten:

Beitrag von Marcus Breuer »

hallo nochmal leute,

ich weiß, ich gehe euch auf den *zeiger. aber denke mir, wer nicht antworten oder lesen will, der muss es ja auch nicht machen. ich habe grob eine vorstellung davon, wie ich jetzt das problem lösen könnte. das problem ist, ich kenne die methode nicht, mit der das wertepaar berechnet wird, da ich diese nicht schreiben muss.

also ich starte mal: und zwar hat franzf mir ja schon einen guten tipp gegeben. in meiner klasse mainwindow sind die signale und slots definiert, die dann auch die berechnung des wertepaares startet.

Code: Alles auswählen

#ifndef MAINWINDOW_H
#define MAINWINDOW_H


#include<QtGui>
#include<QFileDialog>
#include<QPushButton>
#include "ui_mainwindow.h"


class Hauptfenster : public QMainWindow,
                     private Ui::MainWindow {

Q_OBJECT

public:
Hauptfenster();
~Hauptfenster () {};

public slots:
void openFile();
void calculate();

};


#endif // MAINWINDOW_H
und die.cpp:

Code: Alles auswählen

#include "mainwindow.h"

Hauptfenster::Hauptfenster() {
    setupUi(this);


    //Signal-Slot-Verbindungen
    //Menü
    connect ( actionQuit, SIGNAL(triggered(bool)),
              qApp, SLOT(quit()));
    connect ( actionOpen, SIGNAL(triggered(bool)),
              this, SLOT(openFile()));
    //Button
    connect ( QuitButton, SIGNAL(clicked()),
              qApp, SLOT (quit()));
    connect (CalculateButton, SIGNAL(clicked()),
             this, SLOT());

}

//Funktionen
void Hauptfenster::openFile() {
    QString file = QFileDialog::getOpenFileName(
            this, "Please select datafile",
            QDir::homePath(), "Data(*.dump)");


}
kann ich es nun so machen, dass ich in der graph.h insgesamt vier integer deklariere, wegen drawLine(int, int, int, int) die ich dann an eine weitere funktion etwa void graph::printFunction(int, int, int, int) übergebe, die dann dann via update() die funktion paintEvent(...) neustartet und dann dieses wertepaar zeichnet?

ich vermute, dass es grob in die richtige richtung gehen könnte. ich verstehe allerdings nicht, wie ich dann vermeiden kann, dass wenn das programm gestartet wird nicht irgendwas geplottet wird, denn ohne auf den button Calculate zu klicken, hätten die vier variablen ohne initialisiert zu werden doch irgendeinen wert. im grunde könnte ich ja einfach über eine if-abfrage schauen, ob die werte im zulässigen bereich sind und die nur dann zeichnen, d.h. ich würde die vier ints dann vorher mit unzulässigen werten initialisieren, so das das dann erstmal garnichts passieren würde, bis die berechnung ausgeführt wird. der graf soll allerdings von anfang an sichtbar sein.

in der .cpp oben fehlt natürlich der slot.

bitte seid mit nicht böse, ich will es ja verstehen. nur ich denke und denke drüber nach und komme nicht voran.

danke nochmal an jeden, der hilfsbereit auf meinen wirren post antwortet.

grüße
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag von franzf »

Du solltest dich mit den anderen Programmierern absprechen, dass du erstmal weißt, wie die anderen Klassen (speziell die, die die Daten liefert) zu bedienen sind (Interface etc.). Die haben sicher schon einen Header, den du dir holen kannst.
Und ja, so war es gedacht. Nur - Qt bietet für Primitive schon eigene Klassen, also für ein "drawLine" würde ich nicht 4 Integer speichern, sondern gleich ein QLine-Objekt. Es gibt dann auch noch QPolygon, QPainterPath, etc (wenn du das noch brauchen solltest, nicht dass du am Ende 100 int-Werte speicherst für ein paar Linien und Polygone :P).

Wenn du nun die Qt-Klassen wie QLine etc verwendest, wirst du so nette Funktionen sehen:
* bool QLine::isNull()
* bool QPolygon::isEmpty() (QPolygon erbt von QVector<int>, isEmpty kommt von QVector)
usw.
Wenn du diese nicht mit einem eigenen Konstruktor initialisierst, sondern den Default-Konstruktor verwendest (der ein leeres Objekt erzeugt), solltest du eigentlich überhaupt nichts machen müssen. Ich bin mir nämlich ganz sicher, dass QPainter intelligent genug ist, vor dem Malen zu fragen, ob da in QLine überhaupt Daten drin stecken ;)
padreigh
Beiträge: 340
Registriert: 13. Mai 2010 10:06

Beitrag von padreigh »

bitte sei mir nicht böse aber das sieht so aus als hättest du was wild zusammenkopiert und nicht verstanden wofür bestimmte QKlassen da sind - du mixt zB eine actionQuit (QAction) mit einem Buttonsignal des quitButtons (QButton) von denen KEINE in der .h auftauchen - also alles nicht kompilierbar. Normalerweise verwendest du entweder rohe signale oder du setzt dem Button eine QAction und die triggert dann den Slot - muss man nicht, sollte man aber machen.

Wenn du schon Code postest sollte der minimal Kompilierbar sein ... und sich vor etwas wie qwt zu Drücken weil man es nicht kompiliert bekommt um dann selbst was zu frickeln ... ich denke du investierst da an der Falschen Stelle deine Kraft. Wenn du das richtig machen willst. schnapps dir die Examples die mit Qt kommen und lern Qt. Dann setz das was du machen willst um. Nutze existierende Klassen wo möglich und Leite ab nur wenn nötig.

Wenn du frickeln willst : schnapp dir ein QImage, mach darauf nen QPainter, nimm die Methoden von QPainter und mal was. Wenn du für deine Graphen vorher ein paar x/y Berechnest die du dann mit QPainter::drawLine in das Image zeichnest, kannst du das fertige QImage mittels setPixmap(QPixmap::fromImage(deinBemaltesQImage)) als "Bild" auf ein QLabel malen. Das kommt in deine Gui, kriegt die richtige Größe und du brauchst exact NIX von Qts Klassen ableiten. Wenn du nur eine Datei laden, die Punkte plotten und Anzeigen willst sollte das schnell genug sein.

Willst du irgendwas dynamisches das sich auf Nutzereingaben ändert (meinetwegen durch Koeffizienten einer diffgleichung) und das dann neu Plottet, geht obiger Ansatz ebenfalls, wird nur Komplexer.

Alternativ könntest du eine QGraphicsScene <-- "Was malen" mit QGraphicsView <-- "Hier anzeigen" und QPainterPaths <-- "Linienzüge" nutzen, Beispielcode zum rumspielen findest du zB hier: http://www.qtforum.de/forum/viewtopic.php?p=66032#66032
Patrick (QtCreator 1.3.1, Qt 4.6.3)
---
template = subdirs
Marcus Breuer
Beiträge: 113
Registriert: 31. März 2011 17:19
Wohnort: Aachen
Kontaktdaten:

Beitrag von Marcus Breuer »

morgen leute,

vielen vielen dank für eureo antworten.

@franzf: stümper statt programmierer trifft es eher:) dennoch konnte ich dir relativ gut folgen. jedenfalls soweit, dass ihc gestern abend noch "etwas umsetzen" konnte, das deiner ersten anweisung gefolgt ist und siehe da, ich habe quasi eine funktion plotten können. jedoch sieht der code selbst aus meiner sichtweise bescheiden aus. ich werde noch was mehr mit qt und der referrenz anbändeln heute.

@padreigh: danke auch für deine antwort. es ist nicht weit hergeholt. teilweise sind da stellen zwar nicht komplett kopiert, aber wenn ich etwas gesehen habe, das ich brauchte und das ich irgendwo herbekam, dann habe ich natürlich ertsmal probiert das zu übernehmen. der code, den ich gepostet habe ist alerdings kompilierbar. ich kann ja auch mein programm laufen lassen und es funktioniert auch soweit. habe gestern auch eine "funktion plotten" können.



vielen vielen dank nochmal. darf ich fragen, wie ihr zu qt gekommen seid und wie lange es bei euch gedauert hat, eh das wirklich mal gesessen hat?

grüße
Uwe
Beiträge: 176
Registriert: 9. Oktober 2005 13:37
Wohnort: München

Beitrag von Uwe »

Marcus Breuer hat geschrieben:ich hatte auch uwe rathmann schon geschrieben, ...
Qwt 5.2.1 alleine hat ca. 20000 Downloads auf Sourceforge zu denen dann noch einmal eine Vielzahl von Anwendern kommen, die ihre Pakete über die Linux Distributionen beziehen. Dem gegenüber stehe ich als Einzelner, der die komplette Entwicklung und Support seit 10 Jahren im Alleingang bewältigt ( und glaube mir ich habe durchaus ein Leben ).

Das mindeste was ich erwarte ist aber, dass sich die Anwender an die vorgegeben Support Kanäle halten. Diese sind bewusst öffentlich gewählt, damit sie zur Recherche für sich wiederholende Fragen zur Verfügung stehen. Anfragen per Email akzeptiere ich in der Regel nur, wenn ich einen Grund erkennen kann, warum sie nicht öffentlich gestellt werden - fehlende Kenntnisse nicht offenbaren zu wollen, gehört nicht dazu.
... bekam aber eine weniger hilfreiche antwort.
Was in erster Linie an Deiner Frage lag. Das soll kein Vorwurf sein, aber es bedarf zumindest eines gewissen Grades von Kenntnissen um eine Frage so stellen zu können, dass ein anderer etwas damit anfangen kann. Anfragen mit dem Informationsgehalt "geht nicht, was soll ich tun" haben nun einmal wenig Chancen auf sinnvolle Antworten.

Uwe
Marcus Breuer
Beiträge: 113
Registriert: 31. März 2011 17:19
Wohnort: Aachen
Kontaktdaten:

Beitrag von Marcus Breuer »

herr rathmann,

ich habe ihnen auch keinen vorwurf gemacht. ich habe ihnen allerdings genug gesagt, meiner meinung nach hätte es ausreichen müssen um meine frage zu beantworten. ich habe einen ganzen tag damit verbracht nach einer lösung zu suchen. und erst als letztes habe ich mich an sie gewendet mit dem gedanken, warum nicht direkt an die quelle. ich habe die anweisungen in der install textdatei befolgt und konnte dennoch nicht mit arbeiten.

ich wüsste nicht, was neben dem betriebssystem, qt-version und compiler und trotz genauer befolgung eben dieser install textdatei noch hätte wichtig sein können. und manchmal sind die dinge eben genauso einfach wie: gehrt nicht, warum? mein fehler, ich habe den fehlercode nicht mit reingeschrieben.

weiterhin habe ich mich bereits als programmierversager geoutet, eben in diesem forum.

ich finde es dennoch großartig, dass sie qwt entwickelt haben und es offen zur verfügung steht. ich wünschte, mir würde das auch so "leicht" fallen.

daher tut es mir leid, wenn sie sich durch meine bemerkung angergriffen gefühlt haben, sie war jedoch gänzlich ohne wertung zu verstehen.

freundliche grüße,
marcus breuer
Antworten