Threading notwendig?

Programmierung für GNOME und GTK+, GUI-Erstellung mit Glade.
Handas
User
Beiträge: 7
Registriert: Freitag 17. Februar 2017, 23:32

Threading notwendig?

Beitragvon Handas » Freitag 17. Februar 2017, 23:39

Moin,

Ich hab ein Raspberry pi 2 mit 2 Temperatursensoren. Beide Sensoren sind angeschlossen, laufen und geben Werte zurück.
Beim Python Programm hat momentan nur einen Button zum aktualisieren und 2 editFields zum Anzeigen der Werte.
Die GUI wurde mit Glade entworfen.
Solange ich den Button zur manuellen Dateiabfrage nutze, funktioniert auch alles.
Wenn ich aber automatisch (alle 10s) die Werte aktualisieren möchte, hängt sich die Oberfläche auf und ich bekomme keine werte.

Denn Intervall habe ich durch eine Endlosschleife und einem time.sleep realisiert.
Muss ich hier vielleicht einen neuen Thread benutzen, damit das funktioniert? Oder geht das auch simpler?

Gruß
Handas
Benutzeravatar
BlackJack
Moderator
Beiträge: 33001
Registriert: Dienstag 25. Januar 2005, 23:29
Wohnort: Berlin
Kontaktdaten:

Re: Threading notwendig?

Beitragvon BlackJack » Samstag 18. Februar 2017, 00:05

@Handas: Das geht auch ohne Thread mit `timeout_add()`.
“Programs must be written for people to read, and only incidentally for machines to execute.” — Abelson & Sussman, SICP (preface to the first edition)
Handas
User
Beiträge: 7
Registriert: Freitag 17. Februar 2017, 23:32

Re: Threading notwendig?

Beitragvon Handas » Samstag 18. Februar 2017, 17:03

Gobject konnte ich soweit erfolgreich importieren. Aber beim Aufruf haperts noch.

Beim Versuch timeout_add_seconds aufzurufen, bekomme ich folgende Meldung: "Argument 2 does not allow none as Value".
Wie würden denn ein Aufruf aussehen, bei dem zum Beisspiel alle 5 sek ein print('Test') ausgeführt werden soll?


Gruß
Handas
Benutzeravatar
BlackJack
Moderator
Beiträge: 33001
Registriert: Dienstag 25. Januar 2005, 23:29
Wohnort: Berlin
Kontaktdaten:

Re: Threading notwendig?

Beitragvon BlackJack » Samstag 18. Februar 2017, 18:26

@Handas: Na dann solltest Du nicht `None` als zweites Argument übergeben. Kann es sein das Du da nicht die Funktion oder Methode übergeben hast, sondern sie *aufgerufen* hast und damit deren Rückgabewert als zweites Argument übergeben hast?
“Programs must be written for people to read, and only incidentally for machines to execute.” — Abelson & Sussman, SICP (preface to the first edition)
Handas
User
Beiträge: 7
Registriert: Freitag 17. Februar 2017, 23:32

Re: Threading notwendig?

Beitragvon Handas » Samstag 18. Februar 2017, 19:31

Wie kann ich den die Funktion übergeben, ohne sie aufzurufen?
Benutzeravatar
BlackJack
Moderator
Beiträge: 33001
Registriert: Dienstag 25. Januar 2005, 23:29
Wohnort: Berlin
Kontaktdaten:

Re: Threading notwendig?

Beitragvon BlackJack » Samstag 18. Februar 2017, 20:00

@Handas: Äh, indem Du sie nicht aufrufst? Aufruf sind diese runden Klammern, potentiell mit Argumenten‽ Nicht machen! Nur die Funktion übergeben.
  1. In [30]: print(print)  # Yes!
  2. <built-in function print>
  3.  
  4. In [31]: print(print())  # Noooo!
  5.  
  6. None

Wenn Deine Funktion Argumente hat, dann musst Du eine ohne erstellen die das macht was Du willst. Entweder mit ``def`` eine schreiben, oder beispielsweise bei einer vorhandenen Funktion Argumente mit `functools.partial()` binden. Allerdings muss für regelmässiges Aufrufen von der Hauptschleife aus, die Funktion ja einen passenden Rückgabewert haben:
  1. In [32]: GObject.timeout_add_seconds?
  2. Docstring:
  3. timeout_add(interval, callable, user_data=None,
  4.             priority=None) -> source_id
  5.   callable receives (user_data)
  6. Sets a callable be called repeatedly until it returns False.
  7. Use this if you want to have a timer in the "seconds" range
  8. and do not care about the exact time of the first call of the
  9. timer, use this for more efficient system power usage.
  10. Type:      builtin_function_or_method
“Programs must be written for people to read, and only incidentally for machines to execute.” — Abelson & Sussman, SICP (preface to the first edition)
Handas
User
Beiträge: 7
Registriert: Freitag 17. Februar 2017, 23:32

Re: Threading notwendig?

Beitragvon Handas » Samstag 18. Februar 2017, 20:07

ahh ok. das hilft mir weiter. Danke dafür.

Ich habe hauptsächlich mit Delphi zu tun und dort gibt es nur Funktionsaufrufe und keine Verweise

Gruß
Handas
Benutzeravatar
BlackJack
Moderator
Beiträge: 33001
Registriert: Dienstag 25. Januar 2005, 23:29
Wohnort: Berlin
Kontaktdaten:

Re: Threading notwendig?

Beitragvon BlackJack » Samstag 18. Februar 2017, 21:23

@Handas: Kann ich mir kaum Vorstellen. Wie laufen den dort Rückruffunktionen? Letztlich ist Delphi ja ObjectPascal und Pascal kennt Prozedur- und Funktionstypen.
“Programs must be written for people to read, and only incidentally for machines to execute.” — Abelson & Sussman, SICP (preface to the first edition)
Benutzeravatar
BlackJack
Moderator
Beiträge: 33001
Registriert: Dienstag 25. Januar 2005, 23:29
Wohnort: Berlin
Kontaktdaten:

Re: Threading notwendig?

Beitragvon BlackJack » Samstag 18. Februar 2017, 22:01

So sieht das in (Free)Pascal aus:
  1. program Test;
  2.  
  3. uses glib2;
  4.  
  5. var loop: PGMainLoop;
  6.  
  7. function PrintTest(userData: GPointer): GBoolean; cdecl;
  8. begin
  9.   WriteLn('Test');
  10.   PrintTest := True;
  11. end;
  12.  
  13. begin
  14.   loop := g_main_loop_new(nil, False);
  15.   g_timeout_add(1000, @PrintTest, nil);
  16.   g_main_loop_run(loop);
  17.  
  18.   {Somewhat pointless because the mainloop is never quit.}
  19.   g_main_loop_unref(loop);
  20. end.
“Programs must be written for people to read, and only incidentally for machines to execute.” — Abelson & Sussman, SICP (preface to the first edition)
Handas
User
Beiträge: 7
Registriert: Freitag 17. Februar 2017, 23:32

Re: Threading notwendig?

Beitragvon Handas » Samstag 18. Februar 2017, 23:11

Was dazu gelernt :D
Aber in Delphi hätte ich die Timer Klasse gehabt. Damit wäre das alles ein wenig leichter zu relasieren
Benutzeravatar
BlackJack
Moderator
Beiträge: 33001
Registriert: Dienstag 25. Januar 2005, 23:29
Wohnort: Berlin
Kontaktdaten:

Re: Threading notwendig?

Beitragvon BlackJack » Samstag 18. Februar 2017, 23:27

@Handas: Wie kann denn das mit einer Klasse einfacher werden als *ein* Funktionsaufruf?
“Programs must be written for people to read, and only incidentally for machines to execute.” — Abelson & Sussman, SICP (preface to the first edition)
Handas
User
Beiträge: 7
Registriert: Freitag 17. Februar 2017, 23:32

Re: Threading notwendig?

Beitragvon Handas » Samstag 18. Februar 2017, 23:47

Timer importieren;
timer.intervall:=1000;
timer.enabled:=true;
Programmablauf in der automatisch erzeugten Timer1timer Funktion klatschen;

Das kann ich persönlich leichter nachvollziehen
Benutzeravatar
BlackJack
Moderator
Beiträge: 33001
Registriert: Dienstag 25. Januar 2005, 23:29
Wohnort: Berlin
Kontaktdaten:

Re: Threading notwendig?

Beitragvon BlackJack » Sonntag 19. Februar 2017, 00:31

@Handas: Wenn ich das so verkürzt darstelle wie Du den Timer, dann bleibt von meinem genau das hier übrig:
  1.   g_timeout_add(1000, @PrintTest, nil);

Und dann muss man halt noch die `PrintTest`-Funktion schreiben. Konzeptionell einfacher und weniger Code würde ich mal sagen.

Wenn Du unbedingt mit Klassen arbeiten möchtest, dann würde ich Java empfehlen. ;-)
“Programs must be written for people to read, and only incidentally for machines to execute.” — Abelson & Sussman, SICP (preface to the first edition)
Handas
User
Beiträge: 7
Registriert: Freitag 17. Februar 2017, 23:32

Re: Threading notwendig?

Beitragvon Handas » Sonntag 19. Februar 2017, 10:46

Java ist mir zu überladen.

Vielleicht erscheint der timer mir auch nur leichter wegen der Gewohnheit.

Jetzt funktioniert ja alles. Danke dafür 8)
Benutzeravatar
BlackJack
Moderator
Beiträge: 33001
Registriert: Dienstag 25. Januar 2005, 23:29
Wohnort: Berlin
Kontaktdaten:

Re: Threading notwendig?

Beitragvon BlackJack » Sonntag 19. Februar 2017, 13:54

@Handas: In Java wird einem viel von der IDE abgenommen und dieses konkrete Problem, in einer GUI-Anwendung alle x Sekunden etwas ausgeben, ist mit `javax.swing.Timer` ein Einzeiler:
  1.         new Timer(1000, e -> System.out.println("Test")).start();

Das war früher mal schlimm, als es noch keine Lambda-Syntax in Java gab und man das noch so schreiben musste:
  1.         new Timer(1000, new ActionListener() {
  2.             public void actionPerformed(ActionEvent e) {
  3.                 System.out.println("Test");
  4.             }
  5.         }).start();


Oder mal in ein minimales Programm verpackt in dem noch ein Dialogfenster angezeigt wird damit die GUI-Schleife läuft und man es beenden kann:
  1. import javax.swing.*;
  2.  
  3. public class Main {
  4.     public static void main(String[] args) {
  5.         new Timer(1000, e -> System.out.println("Test")).start();
  6.         JOptionPane.showMessageDialog(null, "Press OK button to end this.");
  7.     }
  8. }
“Programs must be written for people to read, and only incidentally for machines to execute.” — Abelson & Sussman, SICP (preface to the first edition)

Zurück zu „GTK+/GNOME“

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder