Browse Source

init commit

dev
Jingxun 9 months ago
parent
commit
08196ee1d5
  1. 31
      frontend/components_lib/__init__.py
  2. 290
      frontend/components_lib/comp_libs.py
  3. 73
      frontend/components_lib/constant.py
  4. 65
      frontend/components_lib/frame.py
  5. 174
      frontend/components_lib/panel.py
  6. 313
      frontend/static_gui_tmp/data_import_page.py
  7. 203
      frontend/static_gui_tmp/login_page.py
  8. 0
      frontend/static_pages/__init__.py
  9. 195
      frontend/static_pages/login_page.py

31
frontend/components_lib/__init__.py

@ -0,0 +1,31 @@
# encoding: utf-8
"""
@author: Qiancj
@contact: qiancj@risenenergy.com
@file: __init__.py
@create-time: 2023-08-01 13:07
@description: The new python script
"""
__all__ = [
"Frame",
"Panel",
"ComponentWith3Cols",
"DropList",
"InputLabel",
"ButtonGropu",
"FontSize",
"ButtonClass",
"LayoutParams",
"FileDirPickerParam",
"FileDirPicker",
"GridTable",
]
from frontend.components_lib.comp_libs import (
ComponentWith3Cols, DropList, InputLabel, ButtonGropu, FileDirPicker, GridTable
)
from frontend.components_lib.constant import (
FontSize, ButtonClass, LayoutParams, FileDirPickerParam
)
from frontend.components_lib.frame import Frame
from frontend.components_lib.panel import Panel

290
frontend/components_lib/comp_libs.py

@ -0,0 +1,290 @@
# encoding: utf-8
"""
@author: Qiancj
@contact: qiancj@risenenergy.com
@file: components
@create-time: 2023-08-02 08:54
@description: The new python script
"""
import abc
import wx
import wx.grid
from frontend.components_lib.constant import ButtonClass, FontSize
class ComponentWith3Cols:
"""
定义一个象类来实现单行组件例如
文字控件 空格占位 输入控件
"""
@abc.abstractmethod
def __init__(self, parent, text, spacer, data_in, font, layout, *, data_in_obj=None, flag=None):
"""
该方法来实现一些初步的设定
:param parent: obj 父元素
:param text: {
"id": int/ wx.ID_ANY, id
"label": string, 文字控件具体内容
"pos": wx.DefaultPosition, 位置坐标
"size": wx.DefaultSize / wx.Size(weight, height), 大小
"style": 0 目前都是默认还没找到具体用处
}
:param spacer: (weight, height), 空白占位符
:param data_in: {
"id": int/ wx.ID_ANY,
"pos": wx.DefaultPosition,
"size": wx.DefaultSize / wx.Size(weight, height),
"style": 0,
"**kwargs": Any 这个由子类实现时自定义
}
:param font: {
"pointSize": int, 字体大小
"family": [ 字体族
wx.FONTFAMILY_DECORATIVE, wx.FONTFAMILY_DEFAULT, wx.FONTFAMILY_MAX,
wx.FONTFAMILY_MODERN, wx.FONTFAMILY_ROMAN, wx.FONTFAMILY_SCRIPT,
wx.FONTFAMILY_SWISS, wx.FONTFAMILY_TELETYPE, wx.FONTFAMILY_UNKNOWN
],
"style": [ 字体斜体设定
wx.FONTSTYLE_ITALIC, wx.FONTSTYLE_MAX, wx.FONTSTYLE_NORMAL, wx.FONTSTYLE_SLANT
],
"weight": [ 字体粗细设定
wx.FONTWEIGHT_BOLD, wx.FONTWEIGHT_EXTRABOLD, wx.FONTWEIGHT_EXTRAHEAVY,
wx.FONTWEIGHT_EXTRALIGHT, wx.FONTWEIGHT_HEAVY, wx.FONTWEIGHT_INVALID,
wx.FONTWEIGHT_LIGHT, wx.FONTWEIGHT_MAX, wx.FONTWEIGHT_MEDIUM,
wx.FONTWEIGHT_NORMAL, wx.FONTWEIGHT_SEMIBOLD, wx.FONTWEIGHT_THIN
],
"underline": False, 下划线
"faceName": string 字体名称例如 微软雅黑
}
:param layout: (proportion, flag, border)
"""
# 设定文字控件
self._text = wx.StaticText(parent, **text)
# 自动换行截断
self._text.Wrap(-1)
# 设置字体
self._text.SetFont(wx.Font(**font))
# 设置空格占位栏
self._spacer = spacer
# 设定输入控件栏
self._data_in = data_in_obj if data_in_obj else None
# 设置输入控件栏的字体
self._data_in.SetFont(wx.Font(**font))
# 设置输入控件栏的大小
self._data_in.SetMinSize(data_in.get("size", wx.DefaultSize))
@property
def get_item(self):
return
class DropList(ComponentWith3Cols):
def __init__(self, parent, text, spacer, data_in, font, layout):
"""
下拉菜单控件
:param parent:
:param text:
:param spacer:
:param data_in: {
"id": int/ wx.ID_ANY,
"pos": wx.DefaultPosition,
"size": wx.DefaultSize / wx.Size(weight, height),
"style": 0,
"choices": List[Str] 下拉列表元素
}
:param font:
"""
# 配置下拉列表
self.__droplist = wx.Choice(parent, **data_in)
# 默认选择列表中第几个元素
self.__droplist.SetSelection(0)
ComponentWith3Cols.__init__(self, parent, text, spacer, data_in, font, layout, data_in_obj=self.__droplist)
# 这是用于排版的参数,供后续使用
self.__layout = layout
@property
def get_item(self):
# 拼装相应控件元素与排版参数,供后续使用
item = ((self._text, *self.__layout), (self._spacer, *self.__layout), (self._data_in, *self.__layout))
return item
class InputLabel(ComponentWith3Cols):
def __init__(self, parent, text, spacer, data_in, font, layout):
"""
普通输入控件
:param parent:
:param text:
:param spacer:
:param data_in: {
"id": wx.ID_ANY,
"value": wx.EmptyString,
"pos": wx.DefaultPosition,
"size" wx.DefaultSize / wx.Size(weight, height),
"style": 常用0 / wx.TE_PASSWORD 设置文字输入框的类型普通文字或者密码型文字
}
:param font:
"""
# 配置文字输入控件
self.__text_ctrl = wx.TextCtrl(parent, **data_in)
ComponentWith3Cols.__init__(self, parent, text, spacer, data_in, font, layout, data_in_obj=self.__text_ctrl)
self.__layout = layout
@property
def get_item(self):
item = ((self._text, *self.__layout), (self._spacer, *self.__layout), (self._data_in, *self.__layout))
return item
class FileDirPicker(ComponentWith3Cols):
def __init__(self, parent, text, spacer, data_in, font, layout, flag=None):
"""
文件或文件夹选择控件
:param parent:
:param text:
:param spacer:
:param data_in: { 目前只对文件做了支持文件件还没做支持
"id": wx.ID_ANY,
"pos": wx.DefaultPosition,
"size": wx.DefaultSize,
"style": wx.FLP_DEFAULT_STYLE,
"path": "", 默认的路径
"message": "Select a file", 提示选择文件的 message
"wildcard": "*.xlsx,*.xls,*.csv", 限定文件类型
"validator": wx.DefaultValidator, 验证器
"name": "浏览" 这个 name 不生效原因未知
}
:param font:
:param layout:
:param flag: 通过 flag 来判断是文件还是文件夹默认是文件
"""
if not flag:
# 配置文件选择器
self.__file_dir = wx.FilePickerCtrl(parent, **data_in)
ComponentWith3Cols.__init__(self, parent, text, spacer, data_in, font, layout, data_in_obj=self.__file_dir)
self.__layout = layout
@property
def get_item(self):
item = ((self._text, *self.__layout), (self._spacer, *self.__layout), (self._data_in, *self.__layout))
return item
class ButtonGropu:
def __init__(
self,
parent,
exit_btn_name,
submit_btn_name,
spacer,
bottom_spacer,
layout,
font=FontSize.BUTTON_SIZE
):
"""
这是一个每个页面底部 退出和提交 按钮的一个组件组控件
:param parent:
:param exit_btn_name: 取消按钮的名称
:param submit_btn_name: 提交按钮的名称
:param spacer: 按钮间的空白占位
:param bottom_spacer: 按钮距页面底部边框的空白占位
:param layout: 用于排版的参数
:param font:
"""
# 设定按钮的基础参数
__exit = ButtonClass.PRIMEARY_BUTTON.copy()
__exit["label"] = exit_btn_name
__submit = ButtonClass.PRIMEARY_BUTTON.copy()
__submit["label"] = submit_btn_name
self.__layout = layout
# 创建按钮组
self.__exit_btn = wx.Button(parent, **__exit)
self.__spacer = spacer
self.__submit_btn = wx.Button(parent, **__submit)
self.__bottom_spacer = bottom_spacer
# 设定按钮字体
self.__exit_btn.SetFont(wx.Font(**font))
self.__submit_btn.SetFont(wx.Font(**font))
@property
def get_item(self):
item = (
(self.__exit_btn, *self.__layout),
(self.__spacer, *self.__layout),
(self.__submit_btn, *self.__layout),
(self.__bottom_spacer, *self.__layout)
)
return item
class GridTable(wx.grid.Grid):
"""
这个类用来封装表格当前 GUI 中表格几乎样式基本同意将一些通用设置封装到该类中
"""
def __init__(self, parent, _id, pos, size, style):
wx.grid.Grid.__init__(self, parent, _id, pos, size, 0)
# 这里的 style 便是一些通用配置
self.__style = style
def set_table(self, num_cols):
# 从 style 中取出配置参数
col_idx = tuple([i for i in range(num_cols)])
col_names = self.__style.get("col_names", None)
col_wid = self.__style.get("col_wid", None)
edit = self.__style.get("edit", False)
lines = self.__style.get("lines", True)
drag_size = self.__style.get("drag_size", False)
drag_move = self.__style.get("drag_move", False)
drag_rc_size = self.__style.get("drag_rc_size", True)
margins = self.__style.get("margins", (0, 0))
font = self.__style.get("font")
col_align = self.__style.get("col_align")
row_align = self.__style.get("row_align")
cell_align = self.__style.get("cell_align")
size = self.__style.get("size")
# 设置列名
if col_names:
col_name_zip = zip(col_idx, col_names)
[self.SetColLabelValue(*i) for i in col_name_zip]
# 设置默认列宽
if col_wid:
wid_zip = zip(col_idx, col_wid)
[self.SetColSize(*i) for i in wid_zip]
# 设置表格中数据是否可写
self.EnableEditing(edit)
# 设置表格中的分隔线是否可见
self.EnableGridLines(lines)
# 设置是否可以拖拽改变表格大小
self.EnableDragGridSize(drag_size)
# 设置表格与外边框的间隔
self.SetMargins(*margins)
# 设置表格是否可以拖拽列
self.EnableDragColMove(drag_move)
# 设置表格是否可以拖拽行
self.EnableDragRowMove(drag_move)
# 设置表格首付可以拖拽改变列宽
self.EnableDragColSize(drag_rc_size)
# 设置表格是否可以拖拽改变行高
self.EnableDragRowSize(drag_rc_size)
# 设置字体
self.SetFont(wx.Font(**font))
# 设置表头及序号的字体
self.SetLabelFont(wx.Font(**font))
# 设置单元格字体
self.SetDefaultCellFont(wx.Font(**font))
# 设置缩进
self.SetColLabelAlignment(*col_align)
self.SetRowLabelAlignment(*row_align)
self.SetDefaultCellAlignment(*cell_align)
# 设置表格最小大小
self.SetMinSize(wx.Size(*size))
self.SetMaxSize(wx.Size(*size))

73
frontend/components_lib/constant.py

@ -0,0 +1,73 @@
# encoding: utf-8
"""
@author: Qiancj
@contact: qiancj@risenenergy.com
@file: constant
@create-time: 2023-08-02 10:35
@description: The new python script
"""
import wx
class FontSize:
"""
常用的几个字体的参数
"""
TITLE_SIZE = {
"pointSize": 24,
"family": wx.FONTFAMILY_MODERN,
"style": wx.FONTSTYLE_NORMAL,
"weight": wx.FONTWEIGHT_BOLD,
"underline": False,
"faceName": "黑体"
}
NB_SIZE = BUTTON_SIZE = CONTENT_SIZE = {
"pointSize": 14,
"family": wx.FONTFAMILY_MODERN,
"style": wx.FONTSTYLE_NORMAL,
"weight": wx.FONTWEIGHT_NORMAL,
"underline": False,
"faceName": "黑体"
}
class ButtonClass:
"""
按钮参数
"""
PRIMEARY_BUTTON = {
"id": wx.ID_ANY,
"label": "",
"pos": wx.DefaultPosition,
"size": wx.DefaultSize,
"style": 0
}
class LayoutParams:
"""
用于排版的参数
"""
VER_LAYOUT = (0, wx.ALL | wx.ALIGN_CENTER_VERTICAL | wx.EXPAND, 5)
HOR_LAYOUT = (0, wx.ALL | wx.ALIGN_CENTER_HORIZONTAL | wx.EXPAND, 5)
class FileDirPickerParam:
"""
文件或文件夹选择器控件的参数
"""
FILE_OBJ = {
"id": wx.ID_ANY,
"path": "",
"message": "Select a file",
"wildcard": "*.xlsx,*.xls,*.csv",
"pos": wx.DefaultPosition,
"size": wx.DefaultSize,
"style": wx.FLP_DEFAULT_STYLE,
"validator": wx.DefaultValidator,
"name": "浏览"
}
DIR_OBJ = {
}

65
frontend/components_lib/frame.py

@ -0,0 +1,65 @@
# encoding: utf-8
"""
@author: Qiancj
@contact: qiancj@risenenergy.com
@file: frame
@create-time: 2023-08-01 13:09
@description: The new python script
"""
import wx
class Frame(wx.Frame):
"""
做了个简单的封装来完成一些通用的配置
"""
def __init__(
self,
parent,
title,
_id=wx.ID_ANY,
pos=wx.DefaultPosition,
size=wx.DefaultSize,
min_size=(-1, -1),
max_size=(-1, -1),
bg_color=wx.Colour(255, 255, 255),
style=wx.DEFAULT_FRAME_STYLE
):
if isinstance(size, tuple):
size = wx.Size(*size)
if isinstance(bg_color, tuple):
bg_color = wx.Colour(*bg_color)
wx.Frame.__init__(
self,
parent,
title=title,
id=_id,
pos=pos,
size=size,
style=style
)
self.__min_size = min_size
self.__max_size = max_size
self.__body = None
self.__bg_color = bg_color
self._OnInit()
def _OnInit(self):
self.SetSizeHints(wx.Size(*self.__min_size), wx.Size(*self.__max_size))
self.SetBackgroundColour(wx.Colour(255, 255, 255))
def sizer(self, size, orient):
return
def show(self):
pass
def event_bind(self):
pass
def __del__(self):
pass

174
frontend/components_lib/panel.py

@ -0,0 +1,174 @@
# encoding: utf-8
"""
@author: Qiancj
@contact: qiancj@risenenergy.com
@file: panel
@create-time: 2023-08-01 13:27
@description: The new python script
"""
import wx
from frontend.components_lib.comp_libs import ButtonGropu
from frontend.components_lib.constant import FontSize
class Panel(wx.Panel):
"""
Panel 做了简单封装现在页面被我做了结构上的简单划分
空白占位
页面标题
空白占位
页面 content
空白占位
底部按钮组
空白占位
"""
def __init__(
self,
parent,
_id,
pos=wx.DefaultPosition,
size=wx.DefaultSize,
style=wx.TAB_TRAVERSAL
):
wx.Panel.__init__(
self,
parent,
_id,
pos,
size,
style
)
self.page_title = None
self.exit_btn = None
self.submit_btn = None
self.body_sizer = None
@staticmethod
def flex_sizer_generater(rows=0, cols=0, vgap=0, hgap=0):
"""
该方法用来生成一个 flexsizer
:param rows: 行数
:param cols: 列数
:param vgap: 行高
:param hgap: 列宽
:return:
"""
# 创建sizer
out_sizer = wx.FlexGridSizer(rows, cols, vgap, hgap)
# 指定大小调整器是否应灵活地调整其列、行或两者的大小。
out_sizer.SetFlexibleDirection(wx.BOTH)
# 指定大小应该如何在非灵活方向上增长
out_sizer.SetNonFlexibleGrowMode(wx.FLEX_GROWMODE_SPECIFIED)
return out_sizer
def title_components(self, title_obj, font=FontSize.TITLE_SIZE):
"""
该方法用来设定每一页面的标题
:param title_obj: {
"id": ID_ANY,
"label": wx.EmptyString, 标题内容
"pos": wx.DefaultPosition,
"size": wx.DefaultSize,
"style": 0
}
:param font: {
"pointSize": int, 字体大小
"family": [
wx.FONTFAMILY_DECORATIVE, wx.FONTFAMILY_DEFAULT, wx.FONTFAMILY_MAX,
wx.FONTFAMILY_MODERN, wx.FONTFAMILY_ROMAN, wx.FONTFAMILY_SCRIPT,
wx.FONTFAMILY_SWISS, wx.FONTFAMILY_TELETYPE, wx.FONTFAMILY_UNKNOWN
],
"style": [wx.FONTSTYLE_ITALIC, wx.FONTSTYLE_MAX, wx.FONTSTYLE_NORMAL, wx.FONTSTYLE_SLANT],
"weight": [
wx.FONTWEIGHT_BOLD, wx.FONTWEIGHT_EXTRABOLD, wx.FONTWEIGHT_EXTRAHEAVY,
wx.FONTWEIGHT_EXTRALIGHT, wx.FONTWEIGHT_HEAVY, wx.FONTWEIGHT_INVALID,
wx.FONTWEIGHT_LIGHT, wx.FONTWEIGHT_MAX, wx.FONTWEIGHT_MEDIUM,
wx.FONTWEIGHT_NORMAL, wx.FONTWEIGHT_SEMIBOLD, wx.FONTWEIGHT_THIN
],
"underline": False, 是否要下划线
"faceName": string 字体名称
}
:return:
"""
# 创建标题sizer
title_sizer = self.flex_sizer_generater(0, 1, 0, 0)
# 设定标题距离页面顶部的空白占位
title_sizer.Add((0, 10), 0, wx.ALIGN_CENTER_HORIZONTAL, 5)
# 创建标题组件
self.page_title = wx.StaticText(self, **title_obj)
self.page_title.Wrap(-1)
# 设定标题字体
self.page_title.SetFont(wx.Font(**font))
# 将标题组件添加到标题 sizer 中
title_sizer.Add(self.page_title, 0, wx.ALL | wx.ALIGN_CENTER_HORIZONTAL, 5)
# 创建标题底部距离页面body顶部的空白占位
title_sizer.Add((0, 20), 1, wx.EXPAND, 5)
return title_sizer
def content_components(self):
"""
这个方法便是每个页面的 content 部分由子类中实现
:return:
"""
pass
def button_components(
self,
exit_btn_name,
submit_btn_name,
horizontal,
bottom,
layout,
font=FontSize.BUTTON_SIZE
):
"""
这个
:param exit_btn_name: 取消按钮名称
:param submit_btn_name: 提交按钮名称
:param horizontal: 按钮间空白占位
:param bottom: 按钮距离底部的空白占位
:param layout: 用于排版的参数
:param font: 字体
:return:
"""
btn_sizer = self.flex_sizer_generater(0, 3, 0, 0)
# 创建按钮组
btn_group = ((self.exit_btn, *_), _, (self.submit_btn, *_), _) = ButtonGropu(
self, exit_btn_name, submit_btn_name, horizontal, bottom, layout, font).get_item
# 将按钮组添加到按钮 sizer
btn_sizer.AddMany(btn_group)
return btn_sizer
def _OnInit(self, *args, **kwargs):
"""
这是类初始化时的一个 hook在子类中实现调用
:param args:
:param kwargs:
:return:
"""
pass
def __del__(self):
pass

313
frontend/static_gui_tmp/data_import_page.py

@ -0,0 +1,313 @@
# -*- coding: utf-8 -*-
import wx
import wx.xrc
import wx.grid
from frontend.components_lib import (
Panel, Frame, FontSize, LayoutParams, FileDirPicker, FileDirPickerParam, GridTable
)
class DataImportBody(Panel):
"""
整个页面的 body 部分
"""
def __init__(self, parent, _id, pos, size, style, page_title):
"""
:param parent:
:param _id:
:param pos:
:param size:
:param style:
:param page_title: 页面的标题
"""
Panel.__init__(self, parent, _id, pos, size, style)
self.__page_title = page_title
self.notebook = None
self.imp_page = None
self.rec_page = None
# 调用初始化 hook
self._OnInit()
def _OnInit(self, *args, **kwargs):
"""
初始化 hook在这个方法中将 body 中所有的组件集合在一起并添加到一个整体的 sizer
:param args:
:param kwargs:
:return:
"""
# 创建 body sizer
self.body_sizer = wx.BoxSizer(wx.VERTICAL)
# 创建标题组件并添加到 body sizer 中
self.body_sizer.Add(
self.title_components(
{
"id": wx.ID_ANY,
"label": f"{self.__page_title}信息录入",
"pos": wx.DefaultPosition,
"size": wx.DefaultSize,
"style": 0
}
), 0, wx.ALIGN_CENTER_HORIZONTAL | wx.ALL, 5
)
# 创建 content 部分并添加到 body sizer 中
self.body_sizer.Add(
self.content_components(), 0, wx.ALIGN_CENTER_HORIZONTAL, 5
)
# 创建底部按钮组件并添加到 body sizer 中
self.body_sizer.Add(
self.button_components(
"退出", "导入", (80, 0), (0, 5), LayoutParams.VER_LAYOUT
), 0, wx.ALIGN_CENTER_HORIZONTAL, 5
)
def content_components(self):
"""
这是 body 中的 content 部分这个部分是页面的核心部分也是最复杂的部分
:return:
"""
# 创建 content 部分的 sizer
content_sizer = self.flex_sizer_generater(0, 1, 0, 0)
# 创建 notebook 组件,用来实现多标签页切换
self.notebook = wx.Notebook(self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, 0)
# notebook 组件的基本配置设定
self.notebook.SetFont(wx.Font(**FontSize.CONTENT_SIZE))
self.notebook.SetBackgroundColour(wx.Colour(255, 255, 255))
# 创建数据导入页
self.imp_page = ImportPage(self.notebook, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, 0)
# 创建导入记录页
self.rec_page = RecordPage(self.notebook, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, 0)
# 将两页添加到 notebook 中,默认选中 批量导入 页签
self.notebook.AddPage(self.imp_page, "批量导入", True)
self.notebook.AddPage(self.rec_page, "导入记录", False)
# 将 notebook 组件添加到 content sizer 中
content_sizer.Add(self.notebook, 0, wx.ALIGN_CENTER_HORIZONTAL | wx.ALL, 5)
# 配置 content 部分距离底部按钮之间的空白占位,即 margin
content_sizer.Add((0, 1), 1, wx.ALIGN_CENTER_HORIZONTAL | wx.ALL | wx.EXPAND, 5)
return content_sizer
class ImportPage(Panel):
def __init__(self, parent, _id, pos, size, style):
"""
这是 批量导入页的组件元素
:param parent:
:param _id:
:param pos:
:param size:
:param style:
"""
Panel.__init__(self, parent, _id, pos, size, style)
self.file = None
# 基本配置
self.SetFont(wx.Font(**FontSize.CONTENT_SIZE))
self.SetMaxSize(wx.Size(700, 270))
# 调用初始化 hook
self._OnInit()
def _OnInit(self, *args, **kwargs):
"""
初始化 hook将页面整合并做相应的页面配置
:param args:
:param kwargs:
:return:
"""
# 创建页面 sizer
self.page_sizer = wx.BoxSizer(wx.VERTICAL)
# 配置大小
self.page_sizer.SetMinSize(wx.Size(700, 270))
# 获取 content 部分并添加到页面 sizer 中
self.page_sizer.Add(self.content_components(), 0, wx.ALIGN_CENTER_HORIZONTAL, 5)
# 设置sizer
self.SetSizer(self.page_sizer)
self.Layout()
# 自适应最小大小
self.page_sizer.Fit(self)
def content_components(self):
"""
创建 content 部分的组件
:return:
"""
# 创建 content sizer
outer_sizer = self.flex_sizer_generater(2, 1, 0, 0)
# 设置占位将元素垂直居中
outer_sizer.Add((0, 100), *LayoutParams.HOR_LAYOUT)
# 创建文件选择器组件的 sizer
comp_sizer = self.flex_sizer_generater(1, 3, 0, 0)
# 创建文件选择器组件
file_pick = (_, _, (self.file, *_)) = FileDirPicker(
self,
{"id": wx.ID_ANY, "label": "选择文件", "pos": wx.DefaultPosition, "size": wx.DefaultSize, "style": 0},
(5, 0), FileDirPickerParam.FILE_OBJ, FontSize.CONTENT_SIZE, LayoutParams.VER_LAYOUT
).get_item
# 设置文件选择器的大小
self.file.SetMinSize(wx.Size(400, -1))
# 将文件选择器组件添加到 sizer 中
comp_sizer.AddMany(file_pick)
outer_sizer.Add(comp_sizer, 1, wx.EXPAND, 5)
return outer_sizer
class RecordPage(ImportPage):
def __init__(self, parent, _id, pos, size, style):
"""
页面框架都一样继承自批量导入页面
:param parent:
:param _id:
:param pos:
:param size:
:param style:
"""
Panel.__init__(self, parent, _id, pos, size, style)
self.SetFont(wx.Font(**FontSize.CONTENT_SIZE))
self.SetMaxSize(wx.Size(700, 270))
# 调用初始化 hook
self._OnInit()
def grid_generater(self, num_rows, num_cols, style):
"""
该方法是一个表格生成器
:param num_rows: 行数
:param num_cols: 列数
:param style: 这个 style 和其他的组件中的 style不一样这是我自定义的 style
{
"col_names": Tuple[Str], 列名
"col_wid": Tuple[Number]/None, 列宽
"edit": Boolean, 表格中数据是否可写
"lines": Boolean, 表格边框线是否可见
"drag_size": Boolean, 是否可以拖拽修改表格大小
"drag_move": Boolean, 是否可以拖拽移动行和列
"drag_rc_size": Boolean, 是否可以拖拽改变行高和列宽
"margins": Tuple[Number], 外边框间隔
"font": Dict, 字体参数
"col_align": Tuple[Number], 表头的对齐方式
"row_align": Tuple[Number], 序号列对齐方式
"cell_align": Tuple[Number], 单元格对齐方式
"size": Tuple[Number] 表格大小
}
:return:
"""
# 创建表格
table = GridTable(self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, style)
table.CreateGrid(num_rows, num_cols)
# 设置表格各方面样式及配置
table.set_table(num_cols)
return table
def content_components(self):
# 生成表格
out = self.grid_generater(
15, 5,
{
"col_names": ("导入日期", "导入时间", "操作人", "文件名称", "导入状态"),
"col_wid": (104, 101, 86, 190, 110),
"font": FontSize.CONTENT_SIZE,
"col_align": (wx.ALIGN_CENTER, wx.ALIGN_CENTER),
"row_align": (wx.ALIGN_CENTER, wx.ALIGN_CENTER),
"cell_align": (wx.ALIGN_CENTER, wx.ALIGN_CENTER),
"size": (700, 270)
}
)
self.get_data()
return out
def get_data(self):
pass
class DataImportPage(Frame):
def __init__(self, parent, title, size, page_title):
Frame.__init__(self, parent, title=title, size=size)
self.__size = size
self.__page_title = page_title
# 调用最终汇总 hook
self.show()
def sizer(self, size, orient):
"""
创建最外层 sizer
:param size: 大小
:param orient: 对齐方式
:return:
"""
out_sizer = wx.BoxSizer(orient)
out_sizer.SetMinSize(wx.Size(*size))
return out_sizer
def get_body(self, parent, _id, pos, size, style):
"""
获取页面的 body
:param parent:
:param _id:
:param pos:
:param size:
:param style:
:return:
"""
body_panel = DataImportBody(parent, _id, pos, size, style, self.__page_title)
return body_panel
def show(self):
"""
最终汇总配置 hook
:return:
"""
# 获取 body
self.__body = self.get_body(self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL)
# 设置 sizer
self.__body.SetSizer(self.__body.body_sizer)
self.__body.Layout()
# 自适应最小大小
self.__body.body_sizer.Fit(self.__body)
# 创建 frame sizer
frame_sizer = self.sizer(self.__size, wx.VERTICAL)
# 将 body 添加到 frame sizer 中
frame_sizer.Add(self.__body, 0, wx.ALL | wx.ALIGN_CENTER_HORIZONTAL, 5)
# 设置 sizer
self.SetSizer(frame_sizer)
self.Layout()
# 将窗口展示到显示器中心
self.Centre(wx.BOTH)
# 事件绑定
self.event_bind()
def exit_onclick(self, event):
self.Destroy()
def login_onclick(self, event):
idx = self.__body.notebook.GetSelection()
op = "导入" if self.__body.notebook.GetPage(idx) == self.__body.imp_page else "导出"
popup = wx.MessageDialog(None, f"您提交了{op}操作", f"{op}操作", wx.YES_DEFAULT)
if popup.ShowModal() == wx.ID_YES:
self.Close()
def change_btn_name(self, event):
idx = self.__body.notebook.GetSelection()
if self.__body.notebook.GetPage(idx) == self.__body.imp_page:
self.__body.submit_btn.SetLabel("导入")
else:
self.__body.submit_btn.SetLabel("导出")
def event_bind(self):
"""
事件绑定
:return:
"""
self.__body.exit_btn.Bind(wx.EVT_LEFT_UP, self.exit_onclick)
self.__body.submit_btn.Bind(wx.EVT_LEFT_UP, self.login_onclick)
# 给 notebook 绑定页签切换事件
self.__body.notebook.Bind(wx.EVT_NOTEBOOK_PAGE_CHANGED, self.change_btn_name)
if __name__ == '__main__':
app = wx.App()
frame = DataImportPage(None, "数据导入", (800, 510), "积层")
frame.Show()
app.MainLoop()

203
frontend/static_gui_tmp/login_page.py

@ -0,0 +1,203 @@
# encoding: utf-8
"""
@author: Qiancj
@contact: qiancj@risenenergy.com
@file: tests
@create-time: 2023-08-01 14:08
@description: The new python script
"""
import wx
from frontend.components_lib import (
DropList, InputLabel, LayoutParams, Frame, Panel, FontSize
)
class LoginBody(Panel):
"""
这是页面的 body 部分由于页面 body 部分较为复杂所以单独拆分一个类来实现
"""
def __init__(self, parent, _id, pos, size, style):
Panel.__init__(self, parent, _id, pos, size, style)
self.drop_list = None
self.username = None
self.pwd = None
# 调用初始化 hook
self._OnInit()
def _OnInit(self, *args, **kwargs):
"""
初始化 hook在这个方法中将 body 中所有的组件集合在一起并添加到一个整体的 sizer
:param args:
:param kwargs:
:return:
"""
# 创建 body sizer
self.body_sizer = wx.BoxSizer(wx.VERTICAL)
# 创建标题组件并添加到 body sizer 中
self.body_sizer.Add(
self.title_components(
{
"id": wx.ID_ANY,
"label": "登 录",
"pos": wx.DefaultPosition,
"size": wx.DefaultSize,
"style": 0
}
), 0, wx.ALIGN_CENTER_HORIZONTAL, 5
)
# 创建 content 部分的组件并添加到 body sizer 中
self.body_sizer.Add(self.content_components(), 0, wx.ALIGN_CENTER_HORIZONTAL, 5)
# 创建底部按钮组件并添加到 body sizer 中
self.body_sizer.Add(
self.button_components(
"退出", "登录", (80, 0), (0, 15), LayoutParams.VER_LAYOUT
), 0, wx.ALIGN_CENTER_HORIZONTAL, 5)
def content_components(self):
"""
这是 body 中的 content 部分这个部分是页面的核心部分也是最复杂的部分
:return:
"""
# 创建 content 部分的 sizer
content_sizer = self.flex_sizer_generater(0, 3, 0, 0)
# 创建并配置 droplist 组件
# 该组件为三列单行组件,基本格式为 [文字栏][空白占位栏][下拉菜单控件栏]
# 数据结构为 ((文字控件, 排版参数), (空白占位控件, 排版参数), (下拉菜单控件, 排版参数))
# 通过解构赋值来讲下拉菜单控件赋值给 droplist 属性
droplist = (_, _, (self.drop_list, *_)) = DropList(
self,
{"id": wx.ID_ANY, "label": "岗位角色", "pos": wx.DefaultPosition, "size": wx.DefaultSize, "style": 0},
(5, 0),
{
"id": wx.ID_ANY, "pos": wx.DefaultPosition, "size": wx.Size(180, -1), "style": 0,
"choices": [
"积层", "焊接极耳", "三封口", "注液前称重", "注液", "注液后称重", "排气后称重", "容量测试",
"AC1", "AC2", "AC3", "AC4", "补电测试", "入库", "出库装箱", "管理员"
]
},
FontSize.CONTENT_SIZE, LayoutParams.VER_LAYOUT
).get_item
# 创建并配置用户名输入组件
username = (_, _, (self.username, *_)) = InputLabel(
self,
{"id": wx.ID_ANY, "label": "用户姓名", "pos": wx.DefaultPosition, "size": wx.DefaultSize, "style": 0},
(5, 0),
{"id": wx.ID_ANY, "pos": wx.DefaultPosition, "size": wx.Size(180, -1), "style": 0, "value": ""},
FontSize.CONTENT_SIZE, LayoutParams.VER_LAYOUT
).get_item
# 创建并配置密码输入组件
pwd = (_, _, (self.pwd, *_)) = InputLabel(
self,
{"id": wx.ID_ANY, "label": "密 码", "pos": wx.DefaultPosition, "size": wx.DefaultSize, "style": 0},
(5, 0),
{
"id": wx.ID_ANY, "pos": wx.DefaultPosition, "size": wx.Size(180, -1), "style": wx.TE_PASSWORD,
"value": ""
},
FontSize.CONTENT_SIZE, LayoutParams.VER_LAYOUT
).get_item
# 配置 content 部分距离底部按钮之间的空白占位,即 margin
btm_spacer = [(0, 5), *LayoutParams.VER_LAYOUT]
# 将各组件添加到 content sizer 中
content_comp = (*droplist, *username, *pwd, btm_spacer)
content_sizer.AddMany(content_comp)
return content_sizer
class LoginPage(Frame):
"""
登录页面的事件绑定页面展示
"""
def __init__(self, parent, title, size):
Frame.__init__(self, parent, title=title, size=size)
self.__size = size
# 调用 hook
self.show()
def sizer(self, size, orient):
"""
创建整体最外层 sizer 容器
:param size: sizer 大小
:param orient: sizer 中元素的对齐方式
:return:
"""
out_sizer = wx.BoxSizer(orient)
out_sizer.SetMinSize(wx.Size(*size))
return out_sizer
@staticmethod
def get_body(parent, _id, pos, size, style):
"""
调用 body 类来获取页面
:param parent:
:param _id:
:param pos:
:param size:
:param style:
:return:
"""
body_panel = LoginBody(parent, _id, pos, size, style)
return body_panel
def show(self):
"""
最后的汇总 hook
:return:
"""
# 获取整个页面的 body
self.__body = self.get_body(self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL)
# 给 body 设置 sizer
self.__body.SetSizer(self.__body.body_sizer)
self.__body.Layout()
# 自适应最小大小
self.__body.body_sizer.Fit(self.__body)
# 创建最外层的 frame sizer
frame_sizer = self.sizer(self.__size, wx.VERTICAL)
# 将 body 添加到 frame sizer 中
frame_sizer.Add(self.__body, 0, wx.ALL | wx.ALIGN_CENTER_HORIZONTAL, 5)
self.SetSizer(frame_sizer)
self.Layout()
# 将窗口展示在显示器中心
self.Centre(wx.BOTH)
# 绑定事件
self.event_bind()
def event_bind(self):
"""
绑定事件
:return:
"""
# 给两个按钮绑定点击事件
# 这里绑定的事件为当鼠标左键抬起时触发,因为鼠标左键按下还未抬起的时候
# 还有可以后悔的余地,不应该触发事件,但是按下后松开抬起,则是确定要点击该按钮
self.__body.exit_btn.Bind(wx.EVT_LEFT_UP, self.exit_onclick)
self.__body.submit_btn.Bind(wx.EVT_LEFT_UP, self.login_onclick)
# 给密码输入框绑定回车事件
self.__body.pwd.Bind(wx.EVT_KEY_UP, self.on_enter_up)
def on_enter_up(self, event):
key_code = event.GetKeyCode()
if key_code == 13:
self.login_onclick(None)
def exit_onclick(self, event):
self.Destroy()
def login_onclick(self, event):
popup = wx.MessageDialog(None, "您提交了登录操作", "登录操作", wx.YES_DEFAULT)
if popup.ShowModal() == wx.ID_YES:
self.Close()
if __name__ == '__main__':
app = wx.App()
frame = LoginPage(None, "登录", size=(500, 320))
frame.Show()
app.MainLoop()

0
frontend/static_pages/__init__.py

195
frontend/static_pages/login_page.py

@ -0,0 +1,195 @@
# -*- coding: utf-8 -*-
import wx
import wx.xrc
class LoginPage(wx.Frame):
def __init__(self, parent):
wx.Frame.__init__(self, parent, id=wx.ID_ANY, title=wx.EmptyString, pos=wx.DefaultPosition,
size=wx.Size(500, 300), style=wx.DEFAULT_FRAME_STYLE | wx.TAB_TRAVERSAL)
self.SetSizeHints(wx.DefaultSize, wx.DefaultSize)
self.SetFont(wx.Font(24, wx.FONTFAMILY_MODERN, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, "黑体"))
self.SetBackgroundColour(wx.Colour(255, 255, 255))
page_sizer = wx.BoxSizer(wx.VERTICAL)
self.body = wx.Panel(self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL)
body_sizer = wx.BoxSizer(wx.VERTICAL)
title_sizer = wx.FlexGridSizer(0, 1, 0, 0)
title_sizer.SetFlexibleDirection(wx.BOTH)
title_sizer.SetNonFlexibleGrowMode(wx.FLEX_GROWMODE_SPECIFIED)
title_sizer.Add((0, 15), 1, wx.EXPAND, 5)
self.m_staticText1 = wx.StaticText(self.body, wx.ID_ANY, u"登 录", wx.DefaultPosition, wx.DefaultSize, 0)
self.m_staticText1.Wrap(-1)
self.m_staticText1.SetFont(
wx.Font(24, wx.FONTFAMILY_MODERN, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, "黑体"))
title_sizer.Add(self.m_staticText1, 0, wx.ALL | wx.ALIGN_CENTER_HORIZONTAL, 5)
title_sizer.Add((0, 15), 1, wx.EXPAND, 5)
body_sizer.Add(title_sizer, 0, wx.ALIGN_CENTER_HORIZONTAL, 5)
content_sizer = wx.FlexGridSizer(0, 1, 0, 0)
content_sizer.SetFlexibleDirection(wx.BOTH)
content_sizer.SetNonFlexibleGrowMode(wx.FLEX_GROWMODE_SPECIFIED)
self.m_notebook1 = wx.Notebook(self.body, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, 0)
self.m_notebook1.SetFont(
wx.Font(11, wx.FONTFAMILY_MODERN, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, "黑体"))
self.phone_page = wx.Panel(self.m_notebook1, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL)
self.phone_page.SetFont(
wx.Font(14, wx.FONTFAMILY_MODERN, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, "黑体"))
phone_sizer = wx.BoxSizer(wx.VERTICAL)
phone_code_sizer = wx.FlexGridSizer(0, 3, 0, 0)
phone_code_sizer.SetFlexibleDirection(wx.BOTH)
phone_code_sizer.SetNonFlexibleGrowMode(wx.FLEX_GROWMODE_SPECIFIED)
self.phone = wx.StaticText(self.phone_page, wx.ID_ANY, u"手 机", wx.DefaultPosition, wx.DefaultSize, 0)
self.phone.Wrap(-1)
phone_code_sizer.Add(self.phone, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5)
phone_code_sizer.Add((0, 10), 1, wx.EXPAND, 5)
self.phonr_num = wx.TextCtrl(self.phone_page, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.Size(260, -1),
0)
phone_code_sizer.Add(self.phonr_num, 0, wx.ALL, 5)
self.code = wx.StaticText(self.phone_page, wx.ID_ANY, u"验证码", wx.DefaultPosition, wx.DefaultSize, 0)
self.code.Wrap(-1)
phone_code_sizer.Add(self.code, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5)
phone_code_sizer.Add((0, 0), 1, wx.EXPAND, 5)
get_code_sizer = wx.FlexGridSizer(0, 2, 0, 0)
get_code_sizer.SetFlexibleDirection(wx.BOTH)
get_code_sizer.SetNonFlexibleGrowMode(wx.FLEX_GROWMODE_SPECIFIED)
self.phone_code = wx.TextCtrl(self.phone_page, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition, wx.DefaultSize, 0)
get_code_sizer.Add(self.phone_code, 0, wx.ALL, 5)
self.get_code = wx.Button(self.phone_page, wx.ID_ANY, u" 获取手机验证码 ", wx.DefaultPosition, wx.DefaultSize, 0)
self.get_code.SetFont(
wx.Font(12, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, "宋体"))
get_code_sizer.Add(self.get_code, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5)
phone_code_sizer.Add(get_code_sizer, 0, wx.ALIGN_CENTER_HORIZONTAL, 5)
phone_sizer.Add(phone_code_sizer, 0, wx.ALIGN_CENTER_HORIZONTAL, 5)
self.phone_page.SetSizer(phone_sizer)
self.phone_page.Layout()
phone_sizer.Fit(self.phone_page)
self.m_notebook1.AddPage(self.phone_page, u"手机验证码登录", False)
self.account_page = wx.Panel(self.m_notebook1, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TAB_TRAVERSAL)
self.account_page.SetFont(
wx.Font(14, wx.FONTFAMILY_MODERN, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, "黑体"))
account_sizer = wx.BoxSizer(wx.VERTICAL)
account_pwd_sizer = wx.FlexGridSizer(0, 3, 0, 0)
account_pwd_sizer.SetFlexibleDirection(wx.BOTH)
account_pwd_sizer.SetNonFlexibleGrowMode(wx.FLEX_GROWMODE_SPECIFIED)
self.username = wx.StaticText(self.account_page, wx.ID_ANY, u"用户名", wx.DefaultPosition, wx.DefaultSize, 0)
self.username.Wrap(-1)
account_pwd_sizer.Add(self.username, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5)
account_pwd_sizer.Add((10, 0), 1, wx.EXPAND, 5)
self.username_val = wx.TextCtrl(self.account_page, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition,
wx.Size(260, -1), 0)
account_pwd_sizer.Add(self.username_val, 0, wx.ALL, 5)
self.password = wx.StaticText(self.account_page, wx.ID_ANY, u"密 码", wx.DefaultPosition, wx.DefaultSize, 0)
self.password.Wrap(-1)
account_pwd_sizer.Add(self.password, 0, wx.ALL | wx.ALIGN_CENTER_VERTICAL, 5)
account_pwd_sizer.Add((10, 0), 1, wx.EXPAND, 5)
self.m_textCtrl5 = wx.TextCtrl(self.account_page, wx.ID_ANY, wx.EmptyString, wx.DefaultPosition,
wx.Size(260, -1), wx.TE_PASSWORD)
account_pwd_sizer.Add(self.m_textCtrl5, 0, wx.ALL, 5)
account_sizer.Add(account_pwd_sizer, 0, wx.ALIGN_CENTER_HORIZONTAL, 5)
self.account_page.SetSizer(account_sizer)
self.account_page.Layout()
account_sizer.Fit(self.account_page)
self.m_notebook1.AddPage(self.account_page, u"用户名密码登录", True)
content_sizer.Add(self.m_notebook1, 1, wx.EXPAND | wx.ALL, 5)
content_sizer.Add((0, 15), 1, wx.EXPAND, 5)
body_sizer.Add(content_sizer, 0, wx.ALIGN_CENTER_HORIZONTAL, 5)
btn_sizer = wx.FlexGridSizer(0, 3, 0, 0)
btn_sizer.SetFlexibleDirection(wx.BOTH)
btn_sizer.SetNonFlexibleGrowMode(wx.FLEX_GROWMODE_SPECIFIED)
self.exit_btn = wx.Button(self.body, wx.ID_ANY, u"退出", wx.DefaultPosition, wx.DefaultSize, 0)
self.exit_btn.SetFont(wx.Font(14, wx.FONTFAMILY_MODERN, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, "黑体"))
btn_sizer.Add(self.exit_btn, 0, wx.ALL, 5)
btn_sizer.Add((60, 0), 1, wx.EXPAND, 5)
self.submit_btn = wx.Button(self.body, wx.ID_ANY, u"登录", wx.DefaultPosition, wx.DefaultSize, 0)
self.submit_btn.SetFont(
wx.Font(14, wx.FONTFAMILY_MODERN, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL, False, "黑体"))
btn_sizer.Add(self.submit_btn, 0, wx.ALL, 5)
btn_sizer.Add((0, 15), 1, wx.EXPAND, 5)
body_sizer.Add(btn_sizer, 0, wx.ALIGN_CENTER_HORIZONTAL, 5)
self.body.SetSizer(body_sizer)
self.body.Layout()
body_sizer.Fit(self.body)
page_sizer.Add(self.body, 1, wx.EXPAND | wx.ALL, 5)
self.SetSizer(page_sizer)
self.Layout()
self.Centre(wx.BOTH)
# Connect Events
self.m_textCtrl5.Bind(wx.EVT_KEY_UP, self.on_enter_up)
self.exit_btn.Bind(wx.EVT_LEFT_UP, self.on_exit_click)
self.submit_btn.Bind(wx.EVT_LEFT_UP, self.on_sumbit_click)
def __del__(self):
pass
def on_enter_up(self, event):
event.Skip()
def on_exit_click(self, event):
event.Skip()
def on_sumbit_click(self, event):
event.Skip()
if __name__ == '__main__':
app = wx.App()
frame = LoginPage(None)
frame.Show()
app.MainLoop()
Loading…
Cancel
Save