Kein Qwt, eigenes Verfahren

Verschiedenes zu Qt
Pixtar
Beiträge: 97
Registriert: 5. Mai 2010 15:32

Beitrag von Pixtar »

franzf, bist du dir da sicher? In einem anderen Forum stand folgendes sollte den gewünschten Effeckt haben:

Code: Alles auswählen

    QWidget *tWidget = new QWidget(this);
    QTimer tTimer = new QTimer;
    tTimer ->setInterval(10);
    connect(tTimer ,SIGNAL(timeout()),tWidget,SLOT(repaint()));

    QThread tThread;
    tWidget ->moveToThread(&tThread);
    tWidget ->connect(&tThread,SIGNAL(started()),tTimer ,SLOT(start()));
    tWidget ->connect(&tThread,SIGNAL(finished()),tTimer ,SLOT(stop()));
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

Das geht nicht - franzf hat Recht.
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
Pixtar
Beiträge: 97
Registriert: 5. Mai 2010 15:32

Beitrag von Pixtar »

Alles klar, also kann ich lediglich Berechnungen, Initializierungen etc. mit den Threads organisieren und keine Manipulation an GUI-Objekten.

Kann ich eigentlich den Status eine Elterndeklaration ummünzen?
Sprich, aus der "protected: void run();" von QThread ein "public slots: void run();" machen?
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag von franzf »

Pixtar hat geschrieben:Kann ich eigentlich den Status eine Elterndeklaration ummünzen?
Sprich, aus der "protected: void run();" von QThread ein "public slots: void run();" machen?
Sicher kannst du das, aber was bringt es dir? Du hast doch schon start(), und wenn du plötzlich run() als SLOT anbietest kannst du ganz schön Stress bekommen. Insbesondere hast du dann keinen eigenen Thread mehr, da start() run() in nem neuen Thread (Das ist ja betriebssystemabhängig) startet. Wenn du start() umgehst hast du am Ende gar keinen neuen Thread :P
Pixtar
Beiträge: 97
Registriert: 5. Mai 2010 15:32

Beitrag von Pixtar »

Soweit hatte ich garnicht gedacht, es war eher eine generelle Frage ob Qt mir diesen Schritt gewährt oder mein Programm ins Nirvana befördert. ;)

Was es mir bringen würde? *nachdenk* Einziger Vorteil wäre wohl, das ich run(); Parameter mitgeben kann, ansonsten wohl kaum etwas. ^^
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag von franzf »

Qt ist auch nur C++, es gibt halt ein paar spezielle Sachen vor allem im Zusammenhang mit QObject.
Funktionsüberladun/überschreibung gehört zu den C++-Features.

Um dein Verhalten zu erreichen, kannst du doch ganz einfach sowas basteln:

Code: Alles auswählen

class MyThread : public QThread {
Q_OBJECT
private:
    void setParam1(const QString& str);
    void setParam2(int val);
public slots:
    void startWithParams(const QString& str, int val) {
        setParam1(str);
        setParam2(val);
        start();
    }
};
enthalten ist natürlich noch nicht der Check, ob der Thread gerade läuft, und entsprechndes restarten. Wenn du das willst.

Ansonsten kannst du auch mal QtConcurrent::run() anschauen, vllt. ist da was für dich dabei.
Uwe
Beiträge: 176
Registriert: 9. Oktober 2005 13:37
Wohnort: München

Beitrag von Uwe »

Ist die Performance bei einer abgeleiteten Klasse von QWidget schneller als die Klasse von QGraphicsView?
QGraphicsView benutzt ebenfalls ein QWidget also ist die Frage ob Du schnelleren Code schreiben kannst als der, der in QGraphicsView Framework implementiert ist. Die Antwort lautet ( bei entsprechenden Fähigkeiten ) in der Regel ja, weil Du Deinen Code auf die entsprechende Situation hin optimieren und unnötigen Balast weglassen kannst. Bei einem Anfänger lautet die Antwort dagegen sicher nein.

Wenn Du ein Oscilloscope mit entsprechender Punktzahl und Bildwiederholrate implementieren willst, kommst Du an OpenGL eigentlich nicht vorbei. D.h anstelle von QPixmap/QWidget solltest Du QGLFramebufferObject/QGLWidget verwenden. Ansonsten mußt Du tricksen wie z.B. das Qwt Qscilloscope Beispiel ( SVN trunk ), das das Bild inkrementell von links nach rechts aufbaut.

Wenn es Dir darum geht Qt/C++ zu lernen ist es natürlich gut wenn Du versuchst grundsätzlich die Abläufe zu verstehen. Wenn Du aber in absehbarer Zeit ein verwertbares Ergebnis brauchst wirst Du ohne Qwt untergehen. Das Schreiben eines performanten Oscilloscopes ( ohne OpenGL ) würden m.E. nicht einmal 5% der Entwickler hinbekommen, die es gewohnt sind täglich mit Qt zu arbeiten.

Uwe
Pixtar
Beiträge: 97
Registriert: 5. Mai 2010 15:32

Beitrag von Pixtar »

Danke für deinen Hinweis Uwe, ich werde meine derzeitige Strategie aber weiter vorsetzen. Bislang geht es gut vorran - vielleicht gehöre ich ja zu den 5%. ^^
Den Leistungsgewinn bei QGLWidget zum QWidget hab ich mir bereits in einigen Examples von Qt angesehen, bei kleinen Sachen war der gering.
Ich werde dann umsteigen wenn ich merke, das es mit dem QWidget nicht mehr funktioniert.
Uwe
Beiträge: 176
Registriert: 9. Oktober 2005 13:37
Wohnort: München

Beitrag von Uwe »

Pixtar hat geschrieben:Den Leistungsgewinn bei QGLWidget zum QWidget hab ich mir bereits in einigen Examples von Qt angesehen, bei kleinen Sachen war der gering.
Bei einem Oscilloscope geht es darum, daß Du eine hohe Bildwiederholrate brauchst - also nicht bloß 2-3 Bilder pro Sekunde. Nehmen wir z.B. ein Zeitfenster von 10 Sekunden mit einem Sample alle 10ms ist das ein Polygon mit 1000 Punkten. Wenn Du das ( eventuell noch mit Kantenglättung ) 50 mal in der Sekunde in Software rendern willst (das macht z.B. die Raster Paint Engine von Qt) wird das schon eng. Und bedenke, daß Du bei einem bewegten Bild jedes mal ein Vollbild rauschiebst, wenn es Dir nicht gelingt, das Zeichnen auf die Hardware zu verlagern.

Du solltest Dir also in jedem Fall vorab überlegen wieviele Punkte mit welcher Bildwiederholrate Du darstellen willst.

Uwe

PS: Ich bin der Autor der Qwt Bibliothek und habe in den letzten Jahren genug Applikationen dieser Art geschrieben um zumindest die Problemstellungen zu kennen.
Pixtar
Beiträge: 97
Registriert: 5. Mai 2010 15:32

Beitrag von Pixtar »

Okay okay, aber leistungsstärkere Maschinen kriegen die Prozeduren deutlich schneller Bearbeitet als beispielsweise ein Laptop mit 1,2 GhZ/512MB.

Weiterhin habe ich das was du ansprichst dem Benutzer überlassen.
Bildwiederholungsrate und Speicherplatz für die Anzahl der Elemente kann der Benutzer selber einstellen, wenn er beispielsweise eine langsame Maschine besitzt.

Ich denke das ich mich damit sehr gut rausgewunden habe. Sprich ruckelt es bei dem Benutzer, so kann er die Optionen einfach zurückschrauben - ähnlich wie bei den Grafikoptionen von Spielen.
Pixtar
Beiträge: 97
Registriert: 5. Mai 2010 15:32

Beitrag von Pixtar »

Ich habe hier gerade ein Problem, was für mich keinen Sinn ergibt.
Ich habe eine QScrollBar erstellt und habe nun das Problem, das sich der Range und die Value der ScrollBar automatisch ändern - ich aber trotzdem eine eigenes Ereignis benötige, das beim Sliderbewegungen eine Funktion auslöst. Sprich connect()

Da das Verändern von value [setValue()] aber valueChange() aufruft bin ich auf sliderMoved() ausgewichen und habe diese mit meiner Funktion connected.

In der Funktion die durch sliderMoved aufgerufen wird, steht der Befehl this->repaint();

Sollte ich nun den Slider bewegen hagelt es nur so Fehlermeldungen:
QWidget::repaint: Recursive repaint detected
QPainter::begin: A paint device can only be painted by one painter at a time.
QPainter::setPen: Painter not active
QWidget::repaint: It is dangerous to leave painters active on a widget outside of the PaintEvent

Ich habe bereits nachgeschlagen, das der Fehler auftritt, wenn repaint oder update im paintEvent aufgerufen werden - was aufkeinenfall so ist, ich hab es schon x-Mal gegengeprüft.

Kann es sein, das irgendeine der Funktionen mit dem paintEvent verknüpft ist? Gemeint sind sliderMoved oder valueChanged, meinen eigenen Funktionen im paintEvent lösen kein neues Event aus. *kopfkratz*
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag von franzf »

Zeig doch mal dein paintEvent(). Und wenn da eigene Funktionen aufgerufen werden, vllt. auch gleich die.
Pixtar
Beiträge: 97
Registriert: 5. Mai 2010 15:32

Beitrag von Pixtar »

Hier der Code:

Code: Alles auswählen

Widget::Widget(){
..
    ScrollBar = new QScrollBar(Qt::Horizontal,this);
    ScrollBar->setGeometry(0,0,400,20);
    connect(ScrollBar,SIGNAL(sliderMoved(int)),this,SLOT(setStatus(int)));
    inner=0;
..
}

void Widget::paintEvent(QPaintEvent *event){
..
    checkInner();
..
}

void Widget::checkInner(){
    inner+=2;
    checkStatus();
}

void Widget::checkStatus(){
    ScrollBar->setGeometry(0,0,this->size().width(),20);
    if(inner>0){
        ScrollBar->setVisible(true);
        ScrollBar->setRange(0,inner);
        ScrollBar->setValue(inner);
    }else
        ScrollBar->setVisible(false);
}

void Widget::setStatus(int value){
    this->repaint();
}
EDIT: Es scheint an dem setValue in checkStatus zu liegen, das mag er nicht .. es steht aber nicht in der Doku von Qt, dass das setValue-Ereignis von QSlider auf das sliderMoved()-Event auslöst.

Irgendwelche Ideen, wie ich die Slider-Variablen verändern kann, ohne das irgendwelche Events ausgelöst werden?
Zuletzt geändert von Pixtar am 7. Mai 2010 15:23, insgesamt 1-mal geändert.
Uwe
Beiträge: 176
Registriert: 9. Oktober 2005 13:37
Wohnort: München

Beitrag von Uwe »

Der Sinn eines paintEvents ist es den Inhalt des Widgets zu zeichnen: also nichts ausser QPainter aufmachen und losmalen. Das Manipulieren anderer Widgets ( wie z.B. die scrollbars ) oder auch nur der eigenen Geomtrie gehört da gar nicht rein.

Uwe

PS: Ach ja: manipulieren des Scrollbalken erzeugt natürlich wieder sliderMoved Signale und damit die Rekursion im paintEvent. ( Wenn Du mir nicht glaubst schau Dir den Stack im Debugger an ).
Pixtar
Beiträge: 97
Registriert: 5. Mai 2010 15:32

Beitrag von Pixtar »

Ich glaub dir schon Uwe, aber die Frage ist dann immernoch, wie ich meine ScrollBar veränder ohne ein Ereignis auszulösen, welches ich connected habe ... das Umbauen der Funktionen, das nichts im paintEvent manipuliert wird ist ja kein Problem ...

EDIT: Es würde ja schon reichen, wenn ich den ScrollBar drehen könnte, sprich: Wenn der Null-Punkt rechts ist, anstatt links. (Invertierung)
Antworten