Last active
July 5, 2020 01:37
-
-
Save Yamabiko/e03869700550b4626d65 to your computer and use it in GitHub Desktop.
Python 2.x wxPython 波形を少しずつ変えて描画しようとしたプログラム。日本語を使っているので実行するときはエンコーディングを適当に指定してください。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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