| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593 |
- import PikaStdLib
- import pika_lvgl as lv
- import time
- class MyMeter:
- def __init__(self,
- parent,
- label_text="label",
- value=0,
- value_set=0,
- unit="°C"):
- container = lv.obj(parent)
- container.set_size(200, 250)
- container.clear_flag(lv.obj.FLAG.SCROLLABLE)
- container.set_style_bg_opa(lv.OPA.TRANSP, 0)
- container.set_style_border_width(0, 0)
- meter = lv.meter(container)
- meter.align(lv.ALIGN.TOP_MID, 0, -20)
- meter.set_size(200, 200)
- # Add a scale first
- scale = meter.add_scale()
- meter.set_scale_ticks(
- scale, 51, 2, 10, lv.palette_main(lv.PALETTE.GREY))
- meter.set_scale_major_ticks(scale, 10, 4, 15, lv.color_black(), 10)
- indic = lv.meter_indicator_t()
- # Add a blue arc to the start
- indic = meter.add_arc(scale, 3, lv.palette_main(lv.PALETTE.BLUE), 0)
- meter.set_indicator_start_value(indic, 0)
- meter.set_indicator_end_value(indic, 20)
- # Make the tick lines blue at the start of the scale
- indic = meter.add_scale_lines(scale, lv.palette_main(
- lv.PALETTE.BLUE), lv.palette_main(lv.PALETTE.BLUE), False, 0)
- meter.set_indicator_start_value(indic, 0)
- meter.set_indicator_end_value(indic, 20)
- # Add a red arc to the end
- indic = meter.add_arc(scale, 3, lv.palette_main(lv.PALETTE.RED), 0)
- meter.set_indicator_start_value(indic, 80)
- meter.set_indicator_end_value(indic, 100)
- # Make the tick lines red at the end of the scale
- indic = meter.add_scale_lines(scale, lv.palette_main(
- lv.PALETTE.RED), lv.palette_main(lv.PALETTE.RED), False, 0)
- meter.set_indicator_start_value(indic, 80)
- meter.set_indicator_end_value(indic, 100)
- # Add a needle line indicator
- indic = meter.add_needle_line(
- scale, 4, lv.palette_main(lv.PALETTE.GREY), -10)
- label = lv.label(meter)
- label.set_text(label_text + unit)
- label.align(lv.ALIGN.CENTER, 0, -20)
- value_label = lv.label(meter)
- value_label.align(lv.ALIGN.CENTER, 0, 60)
- value_set_input = InputBox(container, label_text="given", unit=unit)
- value_set_input.align(lv.ALIGN.BOTTOM_MID, 0, 20)
- self.container = container
- self.lv_meter = meter
- self.value_label = value_label
- self.indic = indic
- self.unit = unit
- self.set_value(value)
- def align(self, align, x, y):
- self.container.align(align, x, y)
- def set_value(self, value):
- # str_value = "%.1f" % value
- str_value = str(value)
- self.value_label.set_text(str_value + " " + self.unit)
- self.lv_meter.set_indicator_end_value(self.indic, value)
- class InputBox:
- def __init__(self, parent, label_text="label", value='0.0', unit="", box_num=1, box_width=80):
- self.input_box_list = []
- container = lv.obj(parent)
- container.set_size(110 + box_width * box_num, 50)
- container.clear_flag(lv.obj.FLAG.SCROLLABLE)
- container.set_style_bg_opa(lv.OPA.TRANSP, 0)
- container.set_style_border_width(0, 0)
- label = lv.label(container)
- label.set_text(label_text)
- label.align(lv.ALIGN.LEFT_MID, 0, 0)
- for i in range(box_num):
- input_box = lv.textarea(container)
- input_box.set_size(box_width, 40)
- input_box.align(lv.ALIGN.LEFT_MID, 40 + box_width*i, 0)
- input_box.clear_flag(lv.obj.FLAG.SCROLLABLE)
- input_box.set_one_line(True)
- self.input_box_list.append(input_box)
- input_box.set_text(value)
- input_box.add_event_cb(self.event_cb, lv.EVENT.FOCUSED, None)
- unit_label = lv.label(container)
- unit_label.set_text(unit)
- unit_label.align(lv.ALIGN.LEFT_MID, 50 + box_width*box_num, 0)
- self.container = container
- def align(self, align, x, y):
- self.container.align(align, x, y)
- def set_size(self, width, height):
- self.container.set_size(width, height)
- def event_cb(self, e):
- code = e.get_code()
- ta = e.get_target()
- # kb: KeyBoard = global_dict["keyboard"]
- # if code == lv.EVENT.FOCUSED:
- # kb.set_hiden(False)
- # kb.set_textarea(ta)
- # if code == lv.EVENT.DEFOCUSED:
- # kb.set_textarea(None)
- class ProcessCount:
- def __init__(self, parent, label_text="label", value=0, totle=0):
- container = lv.obj(parent)
- container.set_size(150, 40)
- container.clear_flag(lv.obj.FLAG.SCROLLABLE)
- label = lv.label(container)
- label.set_text(label_text)
- label.align(lv.ALIGN.BOTTOM_MID, 0, 0)
- value_label = lv.label(container)
- value_label.align(lv.ALIGN.TOP_MID, 0, 0)
- self.container = container
- self.value_label = value_label
- self.set_value(value, totle)
- def align(self, align, x, y):
- self.container.align(align, x, y)
- def set_value(self, value, totle):
- self.value_label.set_text(str(value) + " / " + str(totle))
- class TimerView:
- def __init__(self,
- parent,
- label_text="label",
- seconds_this=0,
- seconds_totle=0):
- self.seconds_this = seconds_this
- self.seconds_totle = seconds_totle
- container = lv.obj(parent)
- container.set_size(200, 80)
- container.clear_flag(lv.obj.FLAG.SCROLLABLE)
- label = lv.label(container)
- label.set_text(label_text)
- label.align(lv.ALIGN.TOP_MID, 0, -10)
- label_this = lv.label(container)
- label_this.align(lv.ALIGN.TOP_MID, 0, 10)
- label_totle = lv.label(container)
- label_totle.align(lv.ALIGN.TOP_MID, 0, 30)
- self.container = container
- self.label_this = label_this
- self.label_totle = label_totle
- self.set_value(seconds_this, seconds_totle)
- def align(self, align, x, y):
- self.container.align(align, x, y)
- def set_value(self, seconds_this, seconds_totle):
- self.label_this.set_text(
- "time now" + str(seconds_this//60) + " min " + str(seconds_this % 60) + " s")
- self.label_totle.set_text(
- "time total " + str(seconds_totle//60) + " min " + str(seconds_totle % 60) + " s")
- class PIDPanel:
- def __init__(self, parent, label_text="label"):
- container = lv.obj(parent)
- container.set_size(300, 300)
- container.clear_flag(lv.obj.FLAG.SCROLLABLE)
- label = lv.label(container)
- label.set_text(label_text)
- label.align(lv.ALIGN.TOP_MID, 0, 0)
- label_partition = InputBox(container, label_text="partition")
- label_partition.align(lv.ALIGN.TOP_LEFT, 20, 20)
- label_top = lv.label(container)
- label_top.set_text("top partition")
- label_bottom = lv.label(container)
- label_bottom.set_text("bottom partition")
- label_top.align(lv.ALIGN.TOP_MID, 0, 80)
- label_bottom.align(lv.ALIGN.TOP_MID, 0, 160)
- input_box_P_top = InputBox(container, label_text="P")
- input_box_P_top.align(lv.ALIGN.TOP_LEFT, -20, 100)
- input_box_I_top = InputBox(container, label_text="I")
- input_box_I_top.align(lv.ALIGN.TOP_LEFT, 110, 100)
- input_box_P_bottom = InputBox(container, label_text="P")
- input_box_P_bottom.align(lv.ALIGN.TOP_LEFT, -20, 180)
- input_box_I_bottom = InputBox(container, label_text="I")
- input_box_I_bottom.align(lv.ALIGN.TOP_LEFT, 110, 180)
- self.container = container
- def align(self, align, x, y):
- self.container.align(align, x, y)
- def set_size(self, width, height):
- self.container.set_size(width, height)
- class Button:
- def __init__(self, parent, label_text="label"):
- btn = lv.btn(parent)
- btn.set_size(100, 50)
- btn.clear_flag(lv.obj.FLAG.SCROLLABLE)
- btn.set_style_bg_color(lv.color_white(), 0)
- btn.set_style_text_color(lv.color_black(), 0)
- btn.set_style_border_color(lv.color_black(), 0)
- label = lv.label(btn)
- label.set_text(label_text)
- label.align(lv.ALIGN.CENTER, 0, 0)
- self.is_on = False
- self.btn = btn
- self.label = label
- def align(self, align, x, y):
- self.btn.align(align, x, y)
- def set_text(self, text):
- self.label.set_text(text)
- def set_is_on(self, is_on):
- self.is_on = is_on
- def _event_cb_adapter(self, e):
- code = e.get_code()
- print("btn event:", self.label.get_text(), code)
- self.event_cb(self, e)
- def add_event_cb(self, event_cb, event_type, user_data=None):
- self.event_cb = event_cb
- self.btn.add_event_cb(self._event_cb_adapter, event_type, user_data)
- def set_size(self, width, height):
- self.btn.set_size(width, height)
- class ProcessBar:
- def __init__(self, parent, value=0):
- bar = lv.bar(parent)
- bar.remove_style_all() # To have a clean start
- bar.add_style(bar_style_bg, 0)
- bar.add_style(bar_style_indic, lv.PART.INDICATOR)
- bar.set_size(200, 40)
- self.bar = bar
- self.style_bg = bar_style_bg
- self.style_indic = bar_style_indic
- self.set_value(value)
- def align(self, align, x, y):
- self.bar.align(align, x, y)
- def set_value(self, value, anim=lv.ANIM.ON):
- self.bar.set_value(value, anim)
- def tab1_btnbar1_event_cb(self: "BtnProcessBar", e):
- if self.btn.is_on:
- self.btn.set_is_on(False)
- self.btn.set_text("start")
- self.bar.set_value(0)
- else:
- self.btn.set_is_on(True)
- self.btn.set_text("stop")
- self.bar.set_value(100)
- class BtnProcessBar:
- def __init__(self, parent, label_text="label", value=0):
- container = lv.obj(parent)
- container.set_size(350, 80)
- container.clear_flag(lv.obj.FLAG.SCROLLABLE)
- container.set_style_bg_opa(lv.OPA.TRANSP, 0)
- # 无边框
- container.set_style_border_width(0, 0)
- btn = Button(container, label_text=label_text)
- bar = ProcessBar(container, value=value)
- btn.align(lv.ALIGN.LEFT_MID, 0, 0)
- bar.align(lv.ALIGN.RIGHT_MID, 0, 0)
- self.container = container
- self.btn = btn
- self.bar = bar
- def align(self, align, x, y):
- self.container.align(align, x, y)
- def _event_cb_adapter(self, e):
- self.event_cb(self, e)
- def add_event_cb(self, event_cb, event_type, user_data=None):
- self.event_cb = event_cb
- self.btn.btn.add_event_cb(
- self._event_cb_adapter, event_type, user_data)
- class Chart:
- def __init__(self, parent, label_text="label"):
- container = lv.obj(parent)
- container.set_size(900, 450)
- container.clear_flag(lv.obj.FLAG.SCROLLABLE)
- container.set_style_bg_opa(lv.OPA.TRANSP, 0)
- container.set_style_border_width(0, 0)
- label = lv.label(container)
- label.set_text(label_text)
- label.align(lv.ALIGN.TOP_MID, 0, -20)
- chart = lv.chart(container)
- chart.set_size(800, 400)
- chart.align(lv.ALIGN.CENTER, 0, 0)
- chart.set_type(lv.chart.TYPE.LINE) # Show lines and points too
- # Add two data series
- ser1 = chart.add_series(lv.palette_main(
- lv.PALETTE.RED), lv.chart.AXIS.PRIMARY_Y)
- chart.set_axis_tick(lv.chart.AXIS.PRIMARY_Y, 10, 5, 6, 2, True, 50)
- chart.set_axis_tick(lv.chart.AXIS.PRIMARY_X, 10, 5, 6, 2, True, 50)
- # Set next points on ser1
- chart.set_next_value(ser1, 10)
- chart.set_next_value(ser1, 10)
- chart.set_next_value(ser1, 10)
- chart.set_next_value(ser1, 10)
- chart.set_next_value(ser1, 10)
- chart.set_next_value(ser1, 10)
- chart.set_next_value(ser1, 10)
- chart.set_next_value(ser1, 30)
- chart.set_next_value(ser1, 70)
- chart.set_next_value(ser1, 90)
- chart.refresh()
- self.container = container
- def align(self, align, x, y):
- self.container.align(align, x, y)
- class KeyBoard:
- def __init__(self, parent, label_text="label", is_number=True):
- container = lv.obj(parent)
- if is_number:
- width = 300
- else:
- width = 600
- container.set_size(width, 360)
- container.clear_flag(lv.obj.FLAG.SCROLLABLE)
- # container.set_style_bg_opa(lv.OPA.TRANSP, 0)
- # container.set_style_border_width(0, 0)
- label = lv.label(container)
- label.set_text(label_text)
- label.align(lv.ALIGN.TOP_MID, 0, 0)
- kb = lv.keyboard(container)
- kb.set_size(width, 300)
- kb.align(lv.ALIGN.BOTTOM_MID, 0, 20)
- # kb.add_event_cb(self.event_cb, lv.EVENT.ALL, None)
- if is_number:
- kb.set_mode(lv.keyboard.MODE.NUMBER)
- else:
- kb.set_mode(lv.keyboard.MODE.TEXT_LOWER)
- close_btn = Button(container, label_text="close")
- close_btn.set_size(40, 40)
- close_btn.align(lv.ALIGN.TOP_RIGHT, 0, -10)
- close_btn.btn.add_event_cb(
- self.close_btn_event_cb, lv.EVENT.CLICKED, None)
- container.add_event_cb(
- self.drag_event_cb, lv.EVENT.ALL, None)
- self.is_hidden = True
- self.container = container
- self.close_btn = close_btn
- self.kb = kb
- def close_btn_event_cb(self, e):
- self.set_hiden(True)
- def drag_event_cb(self, e):
- code = e.get_code()
- if code == lv.EVENT.PRESSED:
- indev = lv.indev_get_act()
- self.drag_start_point = indev.get_point()
- self.container_start_x = self.container.get_x()
- self.container_start_y = self.container.get_y()
- self.container.set_align(lv.ALIGN.TOP_LEFT)
- # print("drag start", self.drag_start_point.x, self.drag_start_point.y)
- if code == lv.EVENT.PRESSING:
- indev = lv.indev_get_act()
- drag_point = indev.get_point()
- # print("drag", drag_point.x, drag_point.y)
- self.container.set_pos(
- self.container_start_x + drag_point.x - self.drag_start_point.x, self.container_start_y + drag_point.y - self.drag_start_point.y)
- def event_cb(self, e):
- code = e.get_code()
- ta = e.get_target()
- # if code == lv.EVENT.FOCUSED:
- # self.kb.move_foreground()
- # self.kb.set_textarea(ta)
- # self.kb.clear_flag(lv.obj.FLAG.HIDDEN)
- # if code == lv.EVENT.DEFOCUSED:
- # self.kb.set_textarea(None)
- # self.kb.add_flag(lv.obj.FLAG.HIDDEN)
- def align(self, align, x, y):
- self.container.align(align, x, y)
- def move_foreground(self):
- self.container.move_foreground()
- def move_background(self):
- self.container.move_background()
- def set_hiden(self, is_hidden):
- # print("set_hiden", is_hidden)
- self.is_hidden = is_hidden
- if is_hidden:
- self.container.add_flag(lv.obj.FLAG.HIDDEN)
- else:
- self.container.clear_flag(lv.obj.FLAG.HIDDEN)
- self.move_foreground()
- def switch_hidden(self):
- self.set_hiden(not self.is_hidden)
- def set_textarea(self, ta):
- self.kb.set_textarea(ta)
- def kb_btn_event_cb(self, e):
- # print("kb_btn_event_cb")
- # kb: KeyBoard = global_dict["keyboard"]
- # kb.switch_hidden()
- pass
- def date_time_update_cb(timer):
- # datetime_label = global_dict["datetime_label"]
- asctime = time.asctime()
- # datetime_label.set_text(asctime)
- print(asctime)
- def main():
- global bar_style_bg
- global bar_style_indic
- bar_style_bg = lv.style_t()
- bar_style_indic = lv.style_t()
- bar_style_bg.init()
- bar_style_bg.set_border_color(lv.palette_main(lv.PALETTE.BLUE))
- bar_style_bg.set_border_width(2)
- bar_style_bg.set_pad_all(6) # To make the indicator smaller
- bar_style_bg.set_radius(6)
- bar_style_bg.set_anim_time(1000)
- bar_style_indic.init()
- bar_style_indic.set_bg_opa(lv.OPA.COVER)
- bar_style_indic.set_bg_color(lv.palette_main(lv.PALETTE.BLUE))
- bar_style_indic.set_radius(3)
- # print('hello pikapython!')
- mem = PikaStdLib.MemChecker()
- STATUS_BAR_HEIGHT = 40
- LOGO_WIDTH = 100
- TABVIEW_HEIGHT = 40
- lv.lock()
- status_bar = lv.obj(lv.scr_act())
- status_bar.set_size(lv.pct(100), STATUS_BAR_HEIGHT)
- status_bar.clear_flag(lv.obj.FLAG.SCROLLABLE)
- lv.scr_act().clear_flag(lv.obj.FLAG.SCROLLABLE)
- # logo label
- logo = lv.obj(status_bar)
- logo.set_size(LOGO_WIDTH, STATUS_BAR_HEIGHT)
- logo_label = lv.label(logo)
- logo_label.set_text("logo")
- logo_label.align(lv.ALIGN.CENTER, 0, 0)
- logo.align(lv.ALIGN.LEFT_MID, -20, 0)
- logo.clear_flag(lv.obj.FLAG.SCROLLABLE)
- datetime_label = lv.label(status_bar)
- datetime_label.set_text("2023.12.20 16:20:08")
- datetime_label.align(lv.ALIGN.LEFT_MID, LOGO_WIDTH, 0)
- timer = lv.timer_create_basic()
- timer.set_period(1)
- timer.set_cb(date_time_update_cb)
- # Keyboard
- keyboard = KeyBoard(lv.scr_act(), label_text="", is_number=False)
- keyboard.align(lv.ALIGN.BOTTOM_MID, 0, 0)
- keyboard_btn = Button(status_bar, label_text="keyboard")
- keyboard_btn.align(lv.ALIGN.RIGHT_MID, -20, 0)
- keyboard_btn.set_size(60, 30)
- keyboard_btn.add_event_cb(kb_btn_event_cb, lv.EVENT.ALL, None)
- # 创建一个tabview对象
- tabview = lv.tabview(lv.scr_act(), lv.DIR.TOP, TABVIEW_HEIGHT)
- tabview.clear_flag(lv.obj.FLAG.SCROLLABLE)
- tabview.align(lv.ALIGN.TOP_LEFT, 0, STATUS_BAR_HEIGHT)
- tabview.set_size(lv.pct(100), lv.pct(100) - 10)
- # 添加标签到tabview
- tab1 = tabview.add_tab("run")
- tab2 = tabview.add_tab("debug")
- tab3 = tabview.add_tab("log")
- tab4 = tabview.add_tab("alert")
- tab5 = tabview.add_tab("help")
- tab6 = tabview.add_tab("program")
- tab7 = tabview.add_tab("edit")
- # tab1
- meter_temp_box = MyMeter(tab1, label_text="box temp", unit="°C")
- meter_temp_box.align(lv.ALIGN.TOP_LEFT, 20, 0)
- meter_humi = MyMeter(tab1, label_text="meter humi", unit="%")
- meter_humi.align(lv.ALIGN.TOP_RIGHT, -20, 0)
- meter_temp_tube = MyMeter(tab1, label_text="tube temp", unit="°C")
- meter_temp_tube.align(lv.ALIGN.TOP_MID, 0, 0)
- meter_temp_box.set_value(20)
- meter_humi.set_value(50)
- meter_temp_tube.set_value(30)
- process_count_segment = ProcessCount(
- tab1, label_text="tim", value=0, totle=10)
- process_count_segment.align(lv.ALIGN.BOTTOM_LEFT, 0, -100)
- process_count_loop = ProcessCount(tab1, label_text="loop", value=0, totle=10)
- process_count_loop.align(lv.ALIGN.BOTTOM_LEFT, 160, -100)
- timer_segment = TimerView(tab1, label_text="segment",
- seconds_this=5, seconds_totle=10)
- timer_totle = TimerView(tab1, label_text="timer totle",
- seconds_this=0, seconds_totle=200)
- tab1_process_bar = BtnProcessBar(tab1, label_text="start")
- tab1_process_bar.align(lv.ALIGN.BOTTOM_LEFT, 0, 0)
- tab1_process_bar.add_event_cb(tab1_btnbar1_event_cb, lv.EVENT.CLICKED)
- # tab2
- timer_segment.align(lv.ALIGN.BOTTOM_RIGHT, -220, -20)
- timer_totle.align(lv.ALIGN.BOTTOM_RIGHT, 0, -20)
- pid_circle = PIDPanel(tab2, label_text="loop PID")
- pid_circle.align(lv.ALIGN.TOP_LEFT, 0, 0)
- pid_plate = PIDPanel(tab2, label_text="plate PID")
- pid_plate.align(lv.ALIGN.TOP_LEFT, 300, 0)
- pid_hit = PIDPanel(tab2, label_text="hit PID")
- pid_hit.align(lv.ALIGN.TOP_LEFT, 600, 0)
- pid_hit.set_size(350, 400)
- # 低气压PID
- label_low_pressure = lv.label(pid_hit.container)
- label_low_pressure.set_text("lo pressure PID")
- label_low_pressure.align(lv.ALIGN.BOTTOM_MID, 0, -100)
- input_box_in = InputBox(pid_hit.container, label_text="in", box_num=2)
- input_box_in.align(lv.ALIGN.BOTTOM_LEFT, 0, -50)
- input_box_out = InputBox(pid_hit.container, label_text="out", box_num=2)
- input_box_out.align(lv.ALIGN.BOTTOM_LEFT, 0, 0)
- tab2_btn1 = Button(tab2, label_text="btn1")
- tab2_btn1.align(lv.ALIGN.BOTTOM_RIGHT, -150, 0)
- tab2_btn2 = Button(tab2, label_text="btn2")
- tab2_btn2.align(lv.ALIGN.BOTTOM_RIGHT, -20, 0)
- # tab3
- chart_temp = Chart(tab3, label_text="chart temp")
- chart_temp.align(lv.ALIGN.CENTER, 0, 0)
- tabview.set_act(0, lv.ANIM.OFF)
- lv.unlock()
- mem.max()
- main()
- for i in range(1):
- time.sleep(0.1)
- lv.task_handler()
- lv.deinit()
|