AddSpacer имеет странный цвет - PullRequest
0 голосов
/ 13 октября 2019

Я новичок в создании GUI с Python. Я создаю приложение, которое получает данные из COM-порта и отображает их на графике. Все почти закончено, и я хочу иметь больше пространства между графиком и ползунками, но когда я использую AddSpacer, они имеют другой цвет и выглядят довольно неловко. Вот так

Ниже приведен код программы со случайными данными, чтобы вы могли попробовать на своем компьютере. Любая помощь очень ценится, спасибо!

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

# simple.py

import wx
import serial
import time
import os
import numpy as np
import matplotlib
matplotlib.use('WXAgg')
from collections import deque
import matplotlib.pyplot as plt
import matplotlib.animation as animation
import random
from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas
from matplotlib.backends.backend_wxagg import NavigationToolbar2WxAgg as NavigationToolbar
from matplotlib.figure import Figure

########################################################################
class SerialCom():

    def __init__(self,port,b_rate):
        self.port = port
        self.b_rate = b_rate
        global ser
        ser = serial.Serial()

    def connect(self): #Start connect
        try:
            ser.port = self.port 
            ser.baudrate = self.b_rate 
            ser.timeout=1
            ser.write_timeout = 1
            ser.open()
            return('Connecting...')
        except serial.SerialException:
            return("No serial port found")
        time.sleep(1) #Waiting for connection to initialize

    def status(self):
        x=os.path.exists(self.port)
        if x==1:
            return 'Connected'
        else:
            return 'Disconnected'

    def disconnect(self):
        return('Disconnecting')
        ser.close()
class DataGen(object):
    """ A silly class that generates pseudo-random data for
        display in the plot.
    """
    def __init__(self, init=50):
        self.data = self.init = init

    def next(self):
        self._recalc_data()
        return self.data

    def _recalc_data(self):
        delta = random.uniform(-0.5, 0.5)
        r = random.random()

        if r > 0.9:
            self.data += delta * 15
        elif r > 0.8: 
            # attraction to the initial value
            delta += (0.5 if self.init > self.data else -0.5)
            self.data += delta
        else:
            self.data += delta

########################################################################
class TopPanel(wx.Panel):

    def __init__(self, parent):
        wx.Panel.__init__(self, parent)
        self.datagen = DataGen()
        self.data = [DataGen().next()]
        self.paused = False

        self.InitGraph()

        self.redraw_timer = wx.Timer(self)
        self.Bind(wx.EVT_TIMER, self.on_redraw_timer, self.redraw_timer)        
        self.redraw_timer.Start(50)

    def InitGraph(self):
        # init graph
        self.figure = Figure(dpi = 100)
        self.ax = self.figure.add_subplot(111)

        #set bg, x, y color
        self.ax.set_title('Very important random data', size=14)
        self.ax.grid(True, color='gray')
        self.ax.tick_params(labelsize=8)
        self.canvas = FigureCanvas(self, -1, self.figure)
        self.sizer = wx.BoxSizer(wx.HORIZONTAL)
        self.sizer.Add(self.canvas, 1, wx.LEFT | wx.TOP | wx.EXPAND)
        #self.sizer.AddSpacer(10)
        self.SetSizer(self.sizer)
        #self.vals = deque()
        self.plot_data, = self.ax.plot([], [])
        self.Fit()
    def update_graph(self):
        xmax = len(self.data) if len(self.data) > 50 else 50
        xmin = xmax - 50
        ymin = round(min(self.data), 0) - 1
        ymax = round(max(self.data), 0) + 1


        self.ax.set_xbound(lower=xmin, upper=xmax)
        self.ax.set_ybound(lower=ymin, upper=ymax)

        self.ax.grid(True, color='gray')        

        self.plot_data.set_data(np.arange(len(self.data)),np.array(self.data))
        self.canvas.draw()

    def on_redraw_timer(self, e):
        #data = float(random.randint(1, 50))
        #self.vals.append(data)
            # update plot data
        #length = len(self.vals)
        self.data.append(self.datagen.next())
        self.update_graph()


########################################################################
class BottomPanel(wx.Panel):
    def __init__(self,parent):
        wx.Panel.__init__(self,parent = parent)
        self.InitUI()

    def InitUI(self):

        sizer = wx.GridBagSizer(5, 6)
        self.timer = wx.Timer(self, 1)
        self.timer.Start(1000)
        self.Bind(wx.EVT_TIMER, self.OnTimer, self.timer)

        #Create Sliders
        self.Psld = wx.Slider(self, value=200, minValue=150, maxValue=500, style=wx.SL_HORIZONTAL)
        self.Isld = wx.Slider(self, value=200, minValue=150, maxValue=500, style=wx.SL_HORIZONTAL)
        self.Dsld = wx.Slider(self, value=200, minValue=150, maxValue=500, style=wx.SL_HORIZONTAL)
        sizer.Add(self.Psld, pos=(0, 1), span=(1, 3), flag=wx.TOP|wx.EXPAND, border=10)
        sizer.Add(self.Isld, pos=(1, 1), span=(1, 3), flag=wx.TOP|wx.EXPAND, border=10)
        sizer.Add(self.Dsld, pos=(2, 1), span=(1, 3), flag=wx.TOP|wx.EXPAND, border=10)

        #SliderLabels
        Ptxt = wx.StaticText(self, label="P Term")
        Itxt = wx.StaticText(self, label="I Term")
        Dtxt = wx.StaticText(self, label="D Term")
        sizer.Add(Ptxt, pos=(0, 0), flag=wx.LEFT|wx.TOP|wx.RIGHT, border=10)
        sizer.Add(Itxt, pos=(1, 0), flag=wx.LEFT|wx.TOP|wx.RIGHT, border=10)
        sizer.Add(Dtxt, pos=(2, 0), flag=wx.LEFT|wx.TOP|wx.RIGHT, border=10)

        #Slider Value
        self.Pval = wx.StaticText(self, label='200')
        self.Ival = wx.StaticText(self, label='200')
        self.Dval = wx.StaticText(self, label='200')
        sizer.Add(self.Pval, pos=(0, 4), flag=wx.TOP|wx.RIGHT, border=10)
        sizer.Add(self.Ival, pos=(1, 4), flag=wx.TOP|wx.RIGHT, border=10)
        sizer.Add(self.Dval, pos=(2, 4), flag=wx.TOP|wx.RIGHT, border=10)

        #Slider Event
        self.Psld.Bind(wx.EVT_SCROLL, self.OnSliderScroll)
        self.Isld.Bind(wx.EVT_SCROLL, self.OnSliderScroll)
        self.Dsld.Bind(wx.EVT_SCROLL, self.OnSliderScroll)

        st1 = wx.StaticText(self, label='COM port: ')
        self.text_ctrl = wx.TextCtrl(self)
        connect_btn = wx.Button(self, label='Enter')
        sizer.Add(st1, pos=(0, 5), flag=wx.TOP|wx.RIGHT, border=12)
        sizer.Add(self.text_ctrl, pos=(1, 5), flag=wx.TOP|wx.RIGHT, border=5)
        sizer.Add(connect_btn, pos=(2, 5), flag=wx.TOP|wx.RIGHT|wx.ALIGN_LEFT, border=5)
        connect_btn.Bind(wx.EVT_BUTTON, self.OnPress)

        sizer.AddGrowableCol(1)
        self.SetSizer(sizer)

    def OnSliderScroll(self, e):

        valP = self.Psld.GetValue()
        valI = self.Isld.GetValue()
        valD = self.Dsld.GetValue()

        self.Pval.SetLabel(str(valP))
        self.Ival.SetLabel(str(valI))
        self.Dval.SetLabel(str(valD))

    def OnPress(self,e):
        global Ser
        global statusbar
        com = self.text_ctrl.GetValue()
        if not com:
            statusbar.SetStatusText("Please enter port!")
        else:
            Ser = SerialCom(com,115200)
            statusbar.SetStatusText(Ser.connect())
            statusbar.SetStatusText(com, 1)
            time.sleep(1)

    def OnTimer(self, event):
        if Ser != None:
            statusbar.SetStatusText(Ser.status())

########################################################################
class GuiFrame(wx.Frame):
    def __init__(self,parent,title):
        super().__init__(parent, title = title, size = (750,550))

        top = TopPanel(self)
        bottom = BottomPanel(self)

        self.SetIcon(wx.Icon("icon2.png"))

        global statusbar

        main_sizer = wx.BoxSizer(wx.VERTICAL)
        main_sizer.Add(top, 1, wx.EXPAND)
        main_sizer.AddSpacer(5)
        main_sizer.Add(bottom,0, wx.EXPAND)
        main_sizer.AddSpacer(5)
        self.SetSizer(main_sizer)

        statusbar = self.CreateStatusBar(2)
        statusbar.SetStatusText('Disconnected')

########################################################################
statusbar = None
Ser = None

if __name__ == "__main__":
    app = wx.App()
    frame = GuiFrame(None, title='PID Tuner')
    frame.Show()
    app.MainLoop()

1 Ответ

0 голосов
/ 13 октября 2019

Оказывается, мне нужна дополнительная панель сверху и панель бота.

        self.panel = wx.Panel(self)
        self.panel.SetBackgroundColour('black')
        top = TopPanel(self.panel)
        bottom = BottomPanel(self.panel)

        self.SetIcon(wx.Icon("icon2.png"))

        global statusbar

        sizer = wx.BoxSizer(wx.VERTICAL)
        sizer.Add(top, 1, wx.EXPAND|wx.ALL, 5)
        sizer.AddSpacer(40)
        sizer.Add(bottom, 0, wx.EXPAND|wx.ALL, 5)
        self.panel.SetSizer(sizer)

        statusbar = self.CreateStatusBar(2)
        statusbar.SetStatusText('Disconnected')
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...