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
Threading notwendig?
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
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
@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?
@Handas: Äh, indem Du sie nicht aufrufst? Aufruf sind diese runden Klammern, potentiell mit Argumenten‽ Nicht machen! Nur die Funktion übergeben.
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:
Code: Alles auswählen
In [30]: print(print) # Yes!
<built-in function print>
In [31]: print(print()) # Noooo!
None
Code: Alles auswählen
In [32]: GObject.timeout_add_seconds?
Docstring:
timeout_add(interval, callable, user_data=None,
priority=None) -> source_id
callable receives (user_data)
Sets a callable be called repeatedly until it returns False.
Use this if you want to have a timer in the "seconds" range
and do not care about the exact time of the first call of the
timer, use this for more efficient system power usage.
Type: builtin_function_or_method
@Handas: Kann ich mir kaum Vorstellen. Wie laufen den dort Rückruffunktionen? Letztlich ist Delphi ja ObjectPascal und Pascal kennt Prozedur- und Funktionstypen.
So sieht das in (Free)Pascal aus:
[codebox=delphi file=Unbenannt.pas]program Test;
uses glib2;
var loop: PGMainLoop;
function PrintTest(userData: GPointer): GBoolean; cdecl;
begin
WriteLn('Test');
PrintTest := True;
end;
begin
loop := g_main_loop_new(nil, False);
g_timeout_add(1000, @PrintTest, nil);
g_main_loop_run(loop);
{Somewhat pointless because the mainloop is never quit.}
g_main_loop_unref(loop);
end.[/code]
[codebox=delphi file=Unbenannt.pas]program Test;
uses glib2;
var loop: PGMainLoop;
function PrintTest(userData: GPointer): GBoolean; cdecl;
begin
WriteLn('Test');
PrintTest := True;
end;
begin
loop := g_main_loop_new(nil, False);
g_timeout_add(1000, @PrintTest, nil);
g_main_loop_run(loop);
{Somewhat pointless because the mainloop is never quit.}
g_main_loop_unref(loop);
end.[/code]
@Handas: Wie kann denn das mit einer Klasse einfacher werden als *ein* Funktionsaufruf?
@Handas: Wenn ich das so verkürzt darstelle wie Du den Timer, dann bleibt von meinem genau das hier übrig:
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.
Code: Alles auswählen
g_timeout_add(1000, @PrintTest, nil);
Wenn Du unbedingt mit Klassen arbeiten möchtest, dann würde ich Java empfehlen.
@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:
[codebox=java5 file=Unbenannt.java] new Timer(1000, e -> System.out.println("Test")).start();[/code]
Das war früher mal schlimm, als es noch keine Lambda-Syntax in Java gab und man das noch so schreiben musste:
[codebox=java5 file=Unbenannt.java] new Timer(1000, new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.out.println("Test");
}
}).start();[/code]
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:
[codebox=java5 file=Unbenannt.java] new Timer(1000, e -> System.out.println("Test")).start();[/code]
Das war früher mal schlimm, als es noch keine Lambda-Syntax in Java gab und man das noch so schreiben musste:
[codebox=java5 file=Unbenannt.java] new Timer(1000, new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.out.println("Test");
}
}).start();[/code]
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:
Code: Alles auswählen
import javax.swing.*;
public class Main {
public static void main(String[] args) {
new Timer(1000, e -> System.out.println("Test")).start();
JOptionPane.showMessageDialog(null, "Press OK button to end this.");
}
}