2017-05-20 2 views
0

Vor allem ich neu zu Python also bitte nicht beurteilen mich über Chaos in Code :). Ich versuche kreisförmige Fortschritte zu machen, aber ich stoße auf einige Probleme und finde nicht, was es verursacht. Problem ist setRange (0, 100) oder setMaximum (100) funktioniert nicht, wenn ich SetValue (100) ich alle Kreis gefüllt. Und das zweite Problem ist, dass mein Fortschrittsbalken rückwärts läuft. Kann mir bitte jemand erklären, was ich falsch mache?wxPython benutzerdefinierte progressBar Probleme

enter image description here

Hier ist, was ich bisher:

main.py Datei

import wx 
from src.arc import TestArc 


class bandom(wx.Frame): 

    def __init__(self, parent, id, title): 
     wx.Frame.__init__(self, parent, id, title, size=(800, 600)) 

     self.gauge = TestArc(self) 
     self.gauge.SetFocus() 
     #self.gauge.setMinimun(0) 
     #self.gauge.setMaximun(100) 
     self.gauge.setRange(0, 100) 
     self.gauge.setValue(10) 

     # timer for testing progressbar 
    #  self.timer = wx.Timer(self) 
    #  self.Bind(wx.EVT_TIMER, self.OnTimer, self.timer) 
    #  self.timer.Start(100) 

    #  self.val = 0 

# def OnTimer(self, evt): 
#  self.val += 1 
#  self.gauge.setValue(self.val) 
# 
#  if self.val >= 100: 
#   self.val = 0 
#  #print(self.val) 


class MyApp(wx.App): 
    def OnInit(self): 
     frame = bandom(None, -1, 'Window title here') 
     frame.Show(True) 
     self.SetTopWindow(frame) 
     return True 

    def main(): 
     app = MyApp(0) 
     app.MainLoop() 

if __name__ == '__main__': 
    main() 

und arc.py Datei

class TestArc(wx.Panel): 

def __init__(self, *args, **kwargs): 
    super(TestArc, self).__init__(*args, **kwargs) 

    self.lineWidth = 0 
    self.min = 0 
    self.max = 100 
    self._value = 0 
    self.setText = '---' 
    # self.font = someFont() 
    self.position = wx.Rect() # self.position.Set(x, y, width, height) 
    self.startPoint = math.radians(0) 
    self.endPoint = math.radians(0) 

    self.Bind(wx.EVT_PAINT, self.OnPaint) 

def setRange(self, min, max): 
    self.min = min 
    self.max = max 

    if self.max < self.min: 
     self.max, self.min = self.min, self.max 

    if self._value < self.min: 
     self._value = self.min 
    elif self._value > self.max: 
     self._value = self.max 

    self.Refresh() 

def setMinimun(self, min): 
    self.setRange(min, self.max) 

def setMaximun(self, max): 
    self.setRange(self.min, max) 

def setValue(self, val): 
    if self._value != val: 
     if val < self.min: 
      self._value = self.min 
     elif val > self.max: 
      self._value = self.max 
     else: 
      self._value = val 
     self.Refresh() 


    self.Refresh() 

def setLineWidth(self, lineWidth): 
    self.lineWidth = lineWidth 

def setPosition(self, x, y, width, height): 
    self.position = wx.Rect(x, y, width, height) 

def OnPaint(self, event=None): 
    dc = wx.PaintDC(self) 
    gc = self.MakeGC(dc) 
    self.Draw(gc) 

def MakeGC(self, dc): 
    try: 
     if False: 
      gcr = wx.GraphicsRenderer.GetCairoRenderer 
      gc = gcr() and gcr().CreateContext(dc) 
      if gc is None: 
       wx.MessageBox("Unable to create Cairo Context.", "Oops") 
       gc = wx.GraphicsContext.Create(dc) 
     else: 
      gc = wx.GraphicsContext.Create(dc) 

    except NotImplementedError: 
     dc.DrawText("This build of wxPython does not support the wx.GraphicsContext " 
        "family of classes.", 
        25, 25) 
     return None 
    return gc 

def Draw(self, gc): 

    #middle progressbar line 
    radStart = math.radians(90) 
    radEnd = math.radians(0) 
    path = gc.CreatePath() 
    path.AddArc(80, 80, 50, radStart, radEnd, True) 
    pen = wx.Pen('#000000', 4) 
    pen.SetCap(wx.CAP_BUTT) 
    gc.SetPen(pen) 
    gc.SetBrush(wx.Brush('#000000', wx.TRANSPARENT)) 
    gc.DrawPath(path) 

    #progress bar 
    start = math.radians(90) 
    #r = math.radians(270) 
    arcStep = -270/(self.max - self.min) * self._value 
    end = math.radians(arcStep) 
    path = gc.CreatePath() 
    path.AddArc(80, 80, 50, start, end) 
    pen = wx.Pen('#CC7F32', 15) 
    pen.SetCap(wx.CAP_BUTT) 
    gc.SetPen(pen) 
    gc.SetBrush(wx.Brush('#000000', wx.TRANSPARENT)) 
    gc.DrawPath(path) 

Antwort

1

Es ist ein bisschen grausig, weil Sie Offset alles um 90º, so müssen Sie dafür verantwortlich sein.
Hier geht nichts:

import wx 
import math 
class TestArc(wx.Panel): 

    def __init__(self, *args, **kwargs): 
     super(TestArc, self).__init__(*args, **kwargs) 

     self.lineWidth = 0 
     self.min = -90 
     self.max = 360 
     self._value = 0 
     self.setText = '---' 
     # self.font = someFont() 
     self.position = wx.Rect() # self.position.Set(x, y, width, height) 
     self.startPoint = math.radians(0) 
     self.endPoint = math.radians(0) 
     self.Bind(wx.EVT_PAINT, self.OnPaint) 

    def setRange(self, min, max): 
     self.min = min 
     self.max = max 
     if self._value < self.min: 
      self._value = self.min 
     elif self._value > self.max: 
      self._value = self.max 
     self.Refresh() 

    def setMinimun(self, min): 
     self.setRange(min, self.max) 

    def setMaximun(self, max): 
     self.setRange(self.min, max) 

    def setValue(self, val): 
     if self._value != val: 
      if val < self.min: 
       self._value = self.min 
      elif val > self.max: 
       self._value = self.max 
      else: 
       self._value = val 
     self.Refresh() 

    def setLineWidth(self, lineWidth): 
     self.lineWidth = lineWidth 

    def setPosition(self, x, y, width, height): 
     self.position = wx.Rect(x, y, width, height) 

    def OnPaint(self, event=None): 
     dc = wx.PaintDC(self) 
     gc = self.MakeGC(dc) 
     self.Draw(gc) 

    def MakeGC(self, dc): 
     try: 
      if False: 
       gcr = wx.GraphicsRenderer.GetCairoRenderer 
       gc = gcr() and gcr().CreateContext(dc) 
       if gc is None: 
        wx.MessageBox("Unable to create Cairo Context.", "Oops") 
        gc = wx.GraphicsContext.Create(dc) 
      else: 
       gc = wx.GraphicsContext.Create(dc) 
     except NotImplementedError: 
      dc.DrawText("This build of wxPython does not support the wx.GraphicsContext " 
         "family of classes.", 
         25, 25) 
      return None 
     return gc 

    def Draw(self, gc): 
     #middle progressbar line 
     radStart = math.radians(90) 
     radEnd = math.radians(0) 
     path = gc.CreatePath() 
     path.AddArc(80, 80, 50, radStart, radEnd, True) 
     pen = wx.Pen('#000000', 4) 
     pen.SetCap(wx.CAP_BUTT) 
     gc.SetPen(pen) 
     gc.SetBrush(wx.Brush('#000000', wx.TRANSPARENT)) 
     gc.DrawPath(path) 

     #progress bar 
     start = math.radians(90) 
     #r = math.radians(270) 
     arcStep = 270/(self.max - self.min) * self._value 
     end = math.radians(arcStep) 
     path = gc.CreatePath() 
     path.AddArc(80, 80, 50, start, end) 
     pen = wx.Pen('#CC7F32', 15) 
     pen.SetCap(wx.CAP_BUTT) 
     gc.SetPen(pen) 
     gc.SetBrush(wx.Brush('#000000', wx.TRANSPARENT)) 
     gc.DrawPath(path) 

class bandom(wx.Frame): 

    def __init__(self, parent, id, title): 
     wx.Frame.__init__(self, parent, id, title, size=(800, 600)) 

     self.gauge = TestArc(self) 
     self.gauge.SetFocus() 
     self.gauge.setMinimun(90) 
     self.gauge.setMaximun(360) 
     self.gauge.setValue(90) 

     # timer for testing progressbar 
     self.val = 90 
     self.timer = wx.Timer(self) 
     self.Bind(wx.EVT_TIMER, self.OnTimer, self.timer) 
     self.timer.Start(100) 

    def OnTimer(self, evt): 
     self.val += 2.7 
     self.gauge.setValue(self.val) 
     if self.val >= 360: 
      self.val = 90 

if __name__ == '__main__': 
    app = wx.App() 
    frame = bandom(None, -1, 'Window title here') 
    frame.Show(True) 
    app.MainLoop() 

ich alles in eine Datei für meine Bequemlichkeit schob.
Edit: Der Grund für die Änderung des Maximalwerts auf 360 und die Berechnung des Schritts im Bogen mit 270 besteht darin, dass Sie einen 3/4-Kreis für Ihr Messgerät gewählt haben und den Betrag berechnen, um das Messgerät im Bogenmaß zu erhöhen . Sie hätten Grad oder Bogenmaß verwenden können, aber so oder so wird es zwischen 0 und 270 für Grad oder 0 und 3π/2 für Radiant berechnet. Ursprünglich sagten Sie, dass Sie eine Skala zwischen 0 und 100 benötigten, die einfachste Möglichkeit, das zu arrangieren, besteht darin, den Messuhrzähler um 2,7 anstatt um 1 zu erhöhen/dekrementieren, d.h. 270 Punkte zu reisen/100 (Ihre erforderliche Skala). Es wäre einfacher, das Messgerät bei Punkt 0 anstatt bei 90 zu starten, aber ich nehme an, dass Sie dies entweder als Übung oder aus ästhetischen Gründen tun.
Running:

Edit 2
Ihre letzte Bemerkung 240 Schritte, Konflikte mit der ursprünglichen Frage und anderen Kommentaren zu benötigen, kann aber als entweder 1 oder 2.7 durch Erhöhen des Spurzählers von 1,125 (270/240) eher erreicht werden diesen Code auf meiner Maschine bekomme ich kein "Flackern". Es kann sich um die Geschwindigkeit Ihres Computers handeln und kann sich verbessern, wenn Sie den Wert ändern, den Sie an den Wert wx.Timer, derzeit 100 Millisekunden oder 10 Mal pro Sekunde, übergeben. Denken Sie daran, dass dieser Code im Wesentlichen vorgibt, den Fortschritt einer Aufgabe mithilfe des Timers anzuzeigen. In Wirklichkeit würden Sie Werte in die Anzeige eingeben, die nicht auf einem Timer, sondern auf dem Fortschritt eines tatsächlichen Prozesses basiert.

+0

danke, aber geht immer noch rückwärts jede Idee, wie kann ich das beheben? –

+0

Ich weiß nicht, worauf Sie sich beziehen. Unter Verwendung eines Kompasses/Uhr beginnt mein Code unten im Süden (6), reist im Uhrzeigersinn durch Westen (9), dann nach Norden (12) und endet in Osten (3). Das klingt nicht "rückwärts" –

+0

Sorry ich irre! Vielen Dank –