Skip to content

Instantly share code, notes, and snippets.

@Yamabiko
Last active July 5, 2020 01:37
Show Gist options
  • Save Yamabiko/e03869700550b4626d65 to your computer and use it in GitHub Desktop.
Save Yamabiko/e03869700550b4626d65 to your computer and use it in GitHub Desktop.
Python 2.x wxPython 波形を少しずつ変えて描画しようとしたプログラム。日本語を使っているので実行するときはエンコーディングを適当に指定してください。
#!/bin/env python
#
# Written by yamabiko
# 2015/July/03
import wx
import os
import datetime
import math
canvas_width = 600
canvas_height = 480
PROGRAM_TITLE = "Oscillo view ver. 0.1"
PROGRAM_WRITER = "written by yamabiko"
PROGRAM_DATE = "2015/July/3"
# タイマーの動作モード
TIMER_STOP = 0
TIMER_TESTRUN = 1
TIMER_DUMMY = 10
TIMER_FUNC = {
TIMER_TESTRUN:"Trial run",
TIMER_DUMMY:"Dummy",
}
class OscilloViewer(object):
def __init__(self,
width = canvas_width,
height = canvas_height):
self.canvas_width = width
self.canvas_height = height
self.init_GUI()
self.wave = [[0, 0] for i in range(0, self.canvas_width)]
self.cycle = 10
def init_GUI(self):
# init wx window
self.wx = wx.App(False)
self.frame = wx.Frame(None, wx.ID_ANY, PROGRAM_TITLE,
size = (self.canvas_width + 20, -1))
self.panel = wx.Panel(self.frame, size = (self.canvas_width, self.canvas_height))
self.panel.SetBackgroundColour('#000000')
self.timer = wx.Timer(self.frame)
self.textCtrl = wx.TextCtrl(self.frame,
size = (self.canvas_width, 100),
style=wx.TE_MULTILINE | wx.TE_READONLY)
self.startButton = wx.Button(self.frame, wx.ID_ANY, "START")
self.stopButton = wx.Button(self.frame, wx.ID_ANY, "STOP")
self.frame.CreateStatusBar()
# menu init
filemenu = wx.Menu()
saveLogItem = filemenu.Append(wx.ID_ANY, "&ログを保存", "ログをファイルに保存")
filemenu.AppendSeparator()
exitItem = filemenu.Append(wx.ID_EXIT, "&終了", "終了")
helpmenu = wx.Menu()
aboutItem = helpmenu.Append(wx.ID_ABOUT, "&About", "Information about this program")
menuBar = wx.MenuBar()
menuBar.Append(filemenu, "&ファイル")
menuBar.Append(helpmenu, "&ヘルプ")
self.frame.SetMenuBar(menuBar)
# events
self.frame.Bind(wx.EVT_BUTTON, self.start, self.startButton)
self.frame.Bind(wx.EVT_BUTTON, self.stop, self.stopButton)
self.frame.Bind(wx.EVT_MENU, self.save_log, saveLogItem)
self.frame.Bind(wx.EVT_MENU, self.app_exit, exitItem)
self.frame.Bind(wx.EVT_MENU, self.app_about, aboutItem)
self.frame.Bind(wx.EVT_TIMER, self.OnTimer)
# sizer
self.hsizer = wx.BoxSizer(wx.HORIZONTAL)
self.hsizer.Add(self.startButton, 0, wx.EXPAND)
self.hsizer.Add(self.stopButton, 0, wx.EXPAND)
self.vsizer = wx.BoxSizer(wx.VERTICAL)
self.vsizer.Add(self.panel, 0, wx.SHAPED)
self.vsizer.Add(self.textCtrl, 1, wx.EXPAND)
self.vsizer.Add(self.hsizer, 0, wx.EXPAND)
self.frame.SetSizer(self.vsizer)
self.frame.SetAutoLayout(1)
self.vsizer.Fit(self.frame)
# show window
self.frame.Show(True)
# running function
self.timer_mode = 0
def app_about(self, e):
dlg = wx.MessageDialog(self.frame,
PROGRAM_TITLE + "\n" + PROGRAM_WRITER + " (" + PROGRAM_DATE + ")",
"About Oscillo view",
wx.OK)
dlg.ShowModal()
dlg.Destroy()
def app_exit(self, e):
self.frame.Close(True)
def start_window(self):
self.wx.MainLoop()
def set_wave(self, wave, norm):
w_len = len(wave)
c_len = self.canvas_width
if w_len < c_len:
count = 1
span = c_len / (w_len - 1)
for x in range(0, self.canvas_width):
if count * span < x:
count += 1
normalized = int(wave[count - 1] * float(self.anvas_height) / float(norm))
self.wave[x] = [normalized % self.canvas_height,
normalized % self.canvas_height + 1]
elif w_len == c_len:
for x in range(0, self.canvas_width):
normalized = int(wave[x] * float(self.canvas_height) / float(norm))
self.wave[x] = [normalized % self.canvas_height,
normalized % self.canvas_height + 1]
else:
for x in range(0, self.canvas_width):
left_end = int(float(x) * (float(w_len) / float(c_len)))
right_end = min([
int(float(x + 1) * (float(w_len) / float(c_len))),
w_len])
sliced = wave[left_end:right_end]
normalized_max = int(max(sliced) * float(self.canvas_height) / float(norm))
normalized_min = int(min(sliced) * float(self.canvas_height) / float(norm))
self.wave[x] = [normalized_min % self.canvas_height,
normalized_max % self.canvas_height + 1]
def redraw(self):
dc = wx.ClientDC(self.panel)
dc.Clear()
dc.SetPen(wx.Pen('yellow'))
for x in range(0, self.canvas_width):
dc.DrawLine(x, self.wave[x][0], x, self.wave[x][1])
def OnTimer(self, e):
if self.timer_mode == TIMER_STOP:
self.timer.Stop()
elif self.timer_mode == TIMER_TESTRUN:
self.tf_start()
elif self.timer_mode == TIMER_DUMMY:
1
def start(self, e):
if self.timer_mode == TIMER_TESTRUN:
return
elif self.timer_mode != TIMER_STOP:
dlg = wx.MessageDialog(self.frame,
TIMER_FUNC[self.timer_mode] + "を実行中です。中断して" + TIMER_FUNC[TIMER_TESTRUN] + "を開始しますか?",
"動作の中断と続行",
wx.YES_NO | wx.ICON_QUESTION)
if dlg.ShowModal() != wx.ID_YES:
dlg.Destroy()
return
dlg.Destroy()
self.timer.Stop()
self.write_log("\"" + TIMER_FUNC[self.timer_mode] + "\" was stopped.")
self.timer_mode = TIMER_TESTRUN
self.timer.Start(50)
self.write_log("\"" + TIMER_FUNC[self.timer_mode] + "\" was started.")
def tf_start(self):
if self.cycle >= 200:
self.cycle = 10
else:
self.cycle += 1
new_wave = [(math.sin(float(i) / float(self.cycle) * 3.141592) * 0.8 + 1.0) * 500.0
for i in range(0, 2000)]
self.set_wave(new_wave, 1000)
self.redraw()
def stop(self, e):
if self.timer_mode != TIMER_STOP:
self.write_log("\"" + TIMER_FUNC[self.timer_mode] + "\" was stopped.")
self.timer_mode = TIMER_STOP
def save_log(self, e):
log_text = self.textCtrl.GetValue()
if len(log_text) == 0:
dlg = wx.MessageDialog(self.frame, "ログは空です。", "ログの保存", wx.OK)
dlg.ShowModal()
dlg.Destroy()
else:
dlg = wx.FileDialog(self.frame,
message = "ログの保存",
wildcard = "*.txt",
style = wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT)
if dlg.ShowModal() == wx.ID_OK:
filename = dlg.GetFilename()
dirname = dlg.GetDirectory()
f = open(os.path.join(dirname, filename), 'w')
f.write(log_text)
f.close()
dlg.Destroy()
def write_log(self, text):
now_time = "[" + datetime.datetime.today().strftime("%Y/%m/%d %H:%M:%S") + "]"
self.textCtrl.AppendText(now_time + " " + text + "\n")
if __name__ == '__main__':
osv = OscilloViewer()
osv.start_window()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment