首页 > 编程语言 >为组态王编写的 时间段 选择 控件 python

为组态王编写的 时间段 选择 控件 python

时间:2023-07-04 20:11:53浏览次数:49  
标签:控件 python self 组态王 日期 时间 坐标 按钮 间隔

日历控件使用说明

这是一个专门为组态软件(如组态王, 力控等)设计的时间选择控件,用于选择一个时间段,来进行数据报表的查询.

控件实际由2部分组成,1个UI程序,和1个modbus TCP从机服务器.从机服务器用于UI程序和组态软件的通信.

 

 日期部分, 时间间隔 部分, 支持滚轮 改变日期, 改变时间间隔

Modbus TCP 从机服务器

地址: 127.0.0.1

端口: 9527

地址

数据类型

名称

功能

40001

Int/RW

启动画面

当赋值1时,启动UI画面

40002

-

 

 

40003-40004

Long/R

起始时间

自1970/01/01 8:00起经过的秒

40005-40006

Long/R

结束时间

同上

40007-40008

Long/R

查询间隔

定义每条查询记录间的时间间隔

40009

Int/R

起始-年

 

40010

Int/R

起始-月

 

40011

Int/R

起始-日

 

40012

Int/R

起始-时

 

40013

Int/R

起始-分

 

40014

Int/R

结束-年

 

40015

Int/R

结束-月

 

40016

Int/R

结束-日

 

40017

Int/R

结束-时

 

40018

Int/R

结束-分

 

 

使用时, 应在启动上位机画面时,运行该程序.连接modbusTCP 从机服务器,并组态变量.当需要选择时间段时,将40001置1,则启动选择画面.从其他地址读取选择的结果.

 上代码

  1 import tkinter as tk
  2 import tkinter.font as tkFont
  3 from datetime import date, timedelta, datetime, time
  4 import sys
  5 import modbus_tk
  6 import modbus_tk.defines as cst
  7 from modbus_tk import modbus_tcp
  8 from time import sleep
  9 
 10 
 11 class 日历控件():
 12     def __init__(self, 通讯器):
 13         self.通讯器 = 通讯器
 14         self.起始时间文本 = ''
 15         self.间隔1天 = timedelta(days=1)
 16         self.间隔1周 = timedelta(days=7)
 17         self.间隔1月 = timedelta(days=30)
 18         self.间隔1年 = timedelta(days=365)
 19         self.间隔9天 = timedelta(days=9)
 20         self.时间区尾 = date.today()
 21         self.时间区头 = self.时间区尾 - self.间隔9天
 22         self.中文周 = ['', '周一', '周二', '周三', '周四', '周五', '周六', '周日']
 23         self.选中的起始时间 = None
 24         self.选中的结束时间 = None
 25         self.时间间隔 = 1
 26         self.日期标签列表 = []
 27         self.时间区列表 = []
 28         self.时间位总列表 = []
 29         self.日期列表 = []
 30         self.跟随指针文本 = ''
 31         self.跟随指针控件 = None
 32         self.当前指针对应时间点位ID = -1
 33         self.主窗口 = tk.Tk()
 34         self.绘制窗口()
 35 
 36     def 绘制窗口(self):
 37         self.主窗口.title('查询时间选择')
 38         self.主窗口.geometry('1300x345+20+20')
 39         self.主框架 = tk.Frame(self.主窗口)
 40         self.主框架.pack()
 41         tk.Label(self.主框架, text='请选择查询的时间范围,时间间隔', font=('黑体', 30)).grid(row=0, column=0)
 42         self.cv = tk.Canvas(self.主框架, background='white', width=1300, height=260)
 43         self.cv.grid(row=2, column=0)
 44         self.cv.bind('<Motion>', self.move_handler)
 45         # self.cv.bind('<Button-1>', self.click_handler)
 46         self.cv.bind('<Enter>', self.enter_handler)
 47         self.cv.bind('<Leave>', self.leave_handler)
 48         self.cv.bind('<Button-1>', self.click_handler)
 49         self.cv.bind('<MouseWheel>', self.mwheel_handler)
 50         # 绘制日期区
 51         日期区坐标 = (10, 40)
 52         for j in range(0, 10):
 53             当前行日期 = self.时间区头 + timedelta(days=j)
 54             self.日期列表.append(当前行日期)
 55             日期标签 = self.cv.create_text(日期区坐标[0], 日期区坐标[1] + 20 * j,
 56                                        anchor=tk.W,
 57                                        justify=tk.LEFT,
 58                                        text=当前行日期.isoformat() + self.中文周[当前行日期.isoweekday()])
 59             self.日期标签列表.append(日期标签)
 60             # 根据ID设置元件属性
 61             # self.cv.itemconfigure(日期标签, fill='red')
 62             # 根据ID取属性
 63             # print(self.cv.itemcget(日期标签, 'text'))
 64         # 绘制时间点阵
 65         时间点阵区坐标 = (120, 30)
 66         for j in range(0, 10):
 67             当前行时间点位矩形列表 = []
 68             self.时间位总列表.append(当前行时间点位矩形列表)
 69             for i in range(0, 144):
 70                 当前时间点位矩形 = self.cv.create_rectangle(时间点阵区坐标[0] + i * 8, 时间点阵区坐标[1] + j * 20,
 71                                                     时间点阵区坐标[0] + i * 8 + 8, 时间点阵区坐标[1] + j * 20 + 20)
 72                 当前行时间点位矩形列表.append(当前时间点位矩形)
 73                 self.cv.itemconfigure(当前时间点位矩形, outline='#C0C0C0')
 74         # 绘制日期变更按钮
 75         日期减按钮区坐标 = (10, 5)
 76         日期变动按钮尺寸 = (25, 20)
 77         日期减按钮文本列表 = ['-日', '-周', '-月', '-年']
 78         for i in range(0, 4):
 79             self.cv.create_rectangle(日期减按钮区坐标[0] + i * 日期变动按钮尺寸[0], 日期减按钮区坐标[1],
 80                                      日期减按钮区坐标[0] + i * 日期变动按钮尺寸[0] + 日期变动按钮尺寸[0], 日期减按钮区坐标[1] + 日期变动按钮尺寸[1])
 81             self.cv.create_text(日期减按钮区坐标[0] + i * 日期变动按钮尺寸[0] + 2, 日期减按钮区坐标[1] + 3,
 82                                 anchor=tk.NW,
 83                                 justify=tk.LEFT,
 84                                 text=日期减按钮文本列表[i])
 85         日期加按钮区坐标 = (10, 235)
 86         日期加按钮文本列表 = ['+日', '+周', '+月', '+年']
 87         for i in range(0, 4):
 88             self.cv.create_rectangle(日期加按钮区坐标[0] + i * 日期变动按钮尺寸[0], 日期加按钮区坐标[1],
 89                                      日期加按钮区坐标[0] + i * 日期变动按钮尺寸[0] + 日期变动按钮尺寸[0], 日期加按钮区坐标[1] + 日期变动按钮尺寸[1])
 90             self.cv.create_text(日期加按钮区坐标[0] + i * 日期变动按钮尺寸[0] + 2, 日期加按钮区坐标[1] + 3,
 91                                 anchor=tk.NW,
 92                                 justify=tk.LEFT,
 93                                 text=日期加按钮文本列表[i])
 94         # 绘制时间标尺
 95         for i in range(0, 23):
 96             self.cv.create_line(时间点阵区坐标[0] + (i + 1) * 8 * 6, 时间点阵区坐标[1],
 97                                 时间点阵区坐标[0] + (i + 1) * 8 * 6, 时间点阵区坐标[1] + 20 * 10)
 98         for i in range(0, 24):
 99             self.cv.create_text(时间点阵区坐标[0] + i * 8 * 6 + 24, 15,
100                                 anchor=tk.N,
101                                 justify=tk.LEFT,
102                                 text='%02d' % i)
103         # 绘制 选择结果描述标签
104         self.选择结果描述标签 = self.cv.create_text(150, 235,
105                                             anchor=tk.NW,
106                                             justify=tk.LEFT,
107                                             text='---',
108                                             font=tkFont.Font(family='黑体', size=18))
109         # 时间间隔选择区
110         self.时间间隔选择区 = tk.Frame(self.主框架)
111         self.时间间隔选择区.grid(row=3, column=0, sticky='w')
112         self.时间间隔描述标签 = tk.Label(self.时间间隔选择区, text='时间间隔为: %d 分钟' % self.时间间隔, font=('宋体', 20))
113         self.时间间隔描述标签.grid(row=0, column=0)
114         self.时间间隔描述标签.bind('<MouseWheel>', self.时间间隔描述标签滚动响应())
115         self.设置为1分 = tk.Button(self.时间间隔选择区, text='1分')
116         self.设置为1分.grid(row=0, column=1)
117         self.设置为5分 = tk.Button(self.时间间隔选择区, text='5分')
118         self.设置为5分.grid(row=0, column=2)
119         self.设置为10分 = tk.Button(self.时间间隔选择区, text='10分')
120         self.设置为10分.grid(row=0, column=3)
121         self.设置为30分 = tk.Button(self.时间间隔选择区, text='30分')
122         self.设置为30分.grid(row=0, column=4)
123         self.设置为60分 = tk.Button(self.时间间隔选择区, text='60分')
124         self.设置为60分.grid(row=0, column=5)
125         self.设置加1分 = tk.Button(self.时间间隔选择区, text='+1分')
126         self.设置加1分.grid(row=0, column=6, padx=(30, 0))
127         self.设置减1分 = tk.Button(self.时间间隔选择区, text='-1分')
128         self.设置减1分.grid(row=0, column=7)
129         self.设置加10分 = tk.Button(self.时间间隔选择区, text='+10分')
130         self.设置加10分.grid(row=0, column=8, padx=(30, 0))
131         self.设置减10分 = tk.Button(self.时间间隔选择区, text='-10分')
132         self.设置减10分.grid(row=0, column=9)
133         self.设置加60分 = tk.Button(self.时间间隔选择区, text='+60分')
134         self.设置加60分.grid(row=0, column=10, padx=(30, 0))
135         self.设置减60分 = tk.Button(self.时间间隔选择区, text='-60分')
136         self.设置减60分.grid(row=0, column=11)
137         self.设置为1分.bind('<Button-1>', self.设置时间间隔(1))
138         self.设置为5分.bind('<Button-1>', self.设置时间间隔(5))
139         self.设置为10分.bind('<Button-1>', self.设置时间间隔(10))
140         self.设置为30分.bind('<Button-1>', self.设置时间间隔(30))
141         self.设置为60分.bind('<Button-1>', self.设置时间间隔(60))
142         self.设置加1分.bind('<Button-1>', self.改变时间间隔(1))
143         self.设置加10分.bind('<Button-1>', self.改变时间间隔(10))
144         self.设置加60分.bind('<Button-1>', self.改变时间间隔(60))
145         self.设置减1分.bind('<Button-1>', self.改变时间间隔(-1))
146         self.设置减10分.bind('<Button-1>', self.改变时间间隔(-10))
147         self.设置减60分.bind('<Button-1>', self.改变时间间隔(-60))
148         self.确定按钮 = tk.Button(self.时间间隔选择区, text='确定')
149         self.确定按钮.grid(row=0, column=12, padx=(50, 0))
150         self.确定按钮.bind('<Button-1>', self.ok_action)
151 
152     def move_handler(self, event):
153         # self.跟随指针文本 = '当前坐标 %s , %s ' % (event.x, event.y)
154         # print(type(event.x))
155         # print(int(event.type))
156         时间点阵区坐标 = (120, 30)
157         点位ID = self.坐标转点位ID(event.x, event.y)
158         if 点位ID != -1 and 点位ID != self.当前指针对应时间点位ID:
159 
160             行列 = self.坐标点位转行列(event.x, event.y)
161             row = 行列[0]
162             column = 行列[1]
163             self.cv.coords(self.跟随指针控件,
164                            时间点阵区坐标[0] + column * 8 + 40,
165                            时间点阵区坐标[1] + row * 20 - 10)
166             小时 = column // 6
167             分钟 = column % 6 * 10
168             # print(self.日期标签列表[row]['text'])
169             self.跟随指针文本 = str(self.日期列表[row].day) + '日%02d:%02d' % (小时, 分钟)
170             self.cv.itemconfigure(self.跟随指针控件, text=self.跟随指针文本)
171 
172             self.当前指针对应时间点位ID = 点位ID
173             for 点位行 in self.时间位总列表:
174                 for 点位 in 点位行:
175                     if 点位 == 点位ID:
176                         self.cv.itemconfigure(点位, width=3, outline='#0000FF')
177                     else:
178                         self.cv.itemconfigure(点位, width=1, outline='#C0C0C0')
179         # 在滚动时触发
180         if int(event.type) == 38:
181             # print('滚动引发')
182             if 点位ID != -1:
183                 行列 = self.坐标点位转行列(event.x, event.y)
184             else:
185                 行列 = self.ID转转行列(self.当前指针对应时间点位ID)
186             row = 行列[0]
187             column = 行列[1]
188             self.cv.coords(self.跟随指针控件,
189                            时间点阵区坐标[0] + column * 8 + 40,
190                            时间点阵区坐标[1] + row * 20 - 10)
191             小时 = column // 6
192             分钟 = column % 6 * 10
193             self.跟随指针文本 = str(self.日期列表[row].day) + '日%02d:%02d' % (小时, 分钟)
194             self.cv.itemconfigure(self.跟随指针控件, text=self.跟随指针文本)
195 
196     def 时间间隔描述标签滚动响应(self):
197         def wheel_handler(event):
198             # print('滚动时间间隔描述区')
199             # print(event)
200             if event.delta > 0:
201                 self.改变时间间隔(1)(None)
202             elif event.delta < 0:
203                 self.改变时间间隔(-1)(None)
204         return wheel_handler
205 
206     def enter_handler(self, event):
207         self.跟随指针控件 = self.cv.create_text(event.x, event.y,
208                                           anchor=tk.E,
209                                           justify=tk.LEFT,
210                                           text=self.跟随指针文本)
211 
212     def leave_handler(self, event):
213         self.cv.delete(self.跟随指针控件)
214 
215     def click_handler(self, event):
216         变更日期文本 = self.日期变动按钮区判断(event.x, event.y)
217         行列 = self.坐标点位转行列(event.x, event.y)
218         if 变更日期文本:
219             变更日期文本参数字典 = {
220                 '-日': -1,
221                 '-周': -7,
222                 '-月': -30,
223                 '-年': -365,
224                 '+日': 1,
225                 '+周': 7,
226                 '+月': 30,
227                 '+年': 365,
228             }
229             self.改动时间区(变更日期文本参数字典[变更日期文本])
230             self.刷新范围底色()
231         elif 行列:
232             row = 行列[0]
233             column = 行列[1]
234             if self.选中的起始时间 and self.选中的结束时间:
235                 self.选中的起始时间 = None
236                 self.选中的结束时间 = None
237                 # self.选择结果描述标签.configure(text='取消上次的选择结果,请重新选择查询起始时间')
238                 self.cv.itemconfigure(self.选择结果描述标签, text='取消上次的选择结果,请重新选择查询起始时间')
239             elif not self.选中的起始时间 and self.选中的结束时间:
240                 self.选中的起始时间 = None
241                 self.选中的结束时间 = None
242                 # self.选择结果描述标签.configure(text='取消上次的选择结果,请重新选择查询起始时间')
243                 self.cv.itemconfigure(self.选择结果描述标签, text='取消上次的选择结果,请重新选择查询起始时间')
244             elif not self.选中的起始时间 and not self.选中的结束时间:
245                 self.选中的起始时间 = datetime(self.日期列表[row].year,
246                                         self.日期列表[row].month,
247                                         self.日期列表[row].day,
248                                         column // 6,
249                                         column % 6 * 10)
250                 # self.选择结果描述标签.configure(text='您已选择 %s 作为查询起始时间,请再选择查询结束时间' % self.选中的起始时间.strftime('%Y年%m月%d日 %H:%M'))
251                 self.cv.itemconfigure(self.选择结果描述标签,
252                                       text='您已选择 %s 作为查询起始时间,请再选择查询结束时间' % self.选中的起始时间.strftime('%Y年%m月%d日 %H:%M'))
253             elif self.选中的起始时间 and not self.选中的结束时间:
254                 self.选中的结束时间 = datetime(self.日期列表[row].year,
255                                         self.日期列表[row].month,
256                                         self.日期列表[row].day,
257                                         column // 6,
258                                         column % 6 * 10)
259                 if self.选中的起始时间 > self.选中的结束时间:
260                     临时替换变量 = self.选中的起始时间
261                     self.选中的起始时间 = self.选中的结束时间
262                     self.选中的结束时间 = 临时替换变量
263                 self.刷新结果描述()
264             self.刷新范围底色()
265 
266     def mwheel_handler(self, event):
267         # print(event)
268         日期区坐标 = (10, 40)
269         if ((日期区坐标[0] < event.x < 1800) and
270                 (日期区坐标[1] < event.y < 日期区坐标[1] + 200)):
271             if event.delta > 0:
272                 self.改动时间区(1)
273             else:
274                 self.改动时间区(-1)
275             self.刷新范围底色()
276             # print('滚动')
277             # print(event)
278             # print(dir(event))
279             # print(event.type)
280             self.move_handler(event)
281 
282     def 坐标转点位ID(self, x, y):
283         行列 = self.坐标点位转行列(x, y)
284         点位ID = -1
285         if 行列:
286             点位ID = self.时间位总列表[行列[0]][行列[1]]
287         return 点位ID
288 
289     def 坐标点位转行列(self, x, y):
290         时间点阵区坐标 = (120, 30)
291         点位尺寸 = (8, 20)
292         if ((时间点阵区坐标[0] < x < 时间点阵区坐标[0] + 点位尺寸[0] * 144) and
293                 (时间点阵区坐标[1] < y < 时间点阵区坐标[1] + 点位尺寸[1] * 10)):
294             列序号 = (x - 时间点阵区坐标[0]) // 点位尺寸[0]
295             行序号 = (y - 时间点阵区坐标[1]) // 点位尺寸[1]
296             return 行序号, 列序号
297         else:
298             return None
299 
300     def ID转转行列(self, ID):
301         行序号 = -1
302         列序号 = -1
303         for 行点位 in self.时间位总列表:
304             行序号 += 1
305             列序号 = -1
306             for 点位 in 行点位:
307                 列序号 += 1
308                 if 点位 == ID:
309                     return 行序号, 列序号
310         return None
311 
312     def 日期变动按钮区判断(self, x, y):
313         日期减按钮区坐标 = (10, 5)
314         日期变动按钮尺寸 = (25, 20)
315         日期减按钮文本列表 = ['-日', '-周', '-月', '-年']
316         日期加按钮区坐标 = (10, 235)
317         日期加按钮文本列表 = ['+日', '+周', '+月', '+年']
318         点击的按钮 = None
319         if ((日期减按钮区坐标[0] < x < 日期减按钮区坐标[0] + 日期变动按钮尺寸[0] * 4) and
320                 (日期减按钮区坐标[1] < y < 日期减按钮区坐标[1] + 日期变动按钮尺寸[1] * 1)):
321             点击的按钮 = 日期减按钮文本列表[int((x - 日期减按钮区坐标[0]) // 日期变动按钮尺寸[0])]
322             print('点击了按钮: %s' % 点击的按钮)
323         elif ((日期加按钮区坐标[0] < x < 日期加按钮区坐标[0] + 日期变动按钮尺寸[0] * 4) and
324               (日期加按钮区坐标[1] < y < 日期加按钮区坐标[1] + 日期变动按钮尺寸[1] * 1)):
325             点击的按钮 = 日期加按钮文本列表[int((x - 日期加按钮区坐标[0]) // 日期变动按钮尺寸[0])]
326             print('点击了按钮: %s' % 点击的按钮)
327         else:
328             点击的按钮 = None
329             print('没有点击日期变更按钮')
330         return 点击的按钮
331 
332     def 改动时间区(self, 改动天数):
333         self.时间区尾 = self.时间区尾 + timedelta(days=改动天数)
334         self.时间区头 = self.时间区头 + timedelta(days=改动天数)
335         for j in range(0, 10):
336             当前行日期 = self.时间区头 + timedelta(days=j)
337             self.cv.itemconfigure(self.日期标签列表[j], text=当前行日期.isoformat() + self.中文周[当前行日期.isoweekday()])
338             self.日期列表[j] = 当前行日期
339         # self.刷新范围底色()
340 
341     def 刷新范围底色(self):
342         if not self.选中的起始时间:
343             for 时间位行 in self.时间位总列表:
344                 for 时间位 in 时间位行:
345                     # 时间位.configure(bg='#F0F0F0')
346                     self.cv.itemconfigure(时间位, fill='#FFFFFF')
347         elif self.选中的起始时间 and not self.选中的结束时间:
348             row, column = self.根据选择的时间点判断对应时间位的位置(self.选中的起始时间)
349             if 0 <= row < 10 and 0 <= column < 144:
350                 # self.时间位总列表[row][column].configure(bg='#00FF00')
351                 self.cv.itemconfigure(self.时间位总列表[row][column], fill='#00FF00')
352             选中时间坐标 = self.根据选择的时间点判断对应时间位的位置(self.选中的起始时间)
353             选中时间一维坐标 = 选中时间坐标[0] * 1000 + 选中时间坐标[1]
354             for j in range(0, 10):
355                 for i in range(0, 144):
356                     if j * 1000 + i == 选中时间一维坐标:
357                         # self.时间位总列表[j][i].configure(bg='#00FF00')
358                         self.cv.itemconfigure(self.时间位总列表[j][i], fill='#00FF00')
359                     else:
360                         # self.时间位总列表[j][i].configure(bg='#F0F0F0')
361                         self.cv.itemconfigure(self.时间位总列表[j][i], fill='#FFFFFF')
362         elif self.选中的起始时间 and self.选中的结束时间:
363             起始时间坐标 = self.根据选择的时间点判断对应时间位的位置(self.选中的起始时间)
364             结束时间坐标 = self.根据选择的时间点判断对应时间位的位置(self.选中的结束时间)
365             起始时间一维坐标 = 起始时间坐标[0] * 1000 + 起始时间坐标[1]
366             结束时间一维坐标 = 结束时间坐标[0] * 1000 + 结束时间坐标[1]
367             for j in range(0, 10):
368                 for i in range(0, 144):
369                     if 起始时间一维坐标 <= j * 1000 + i <= 结束时间一维坐标:
370                         # self.时间位总列表[j][i].configure(bg='#00FF00')
371                         self.cv.itemconfigure(self.时间位总列表[j][i], fill='#00FF00')
372                     else:
373                         # self.时间位总列表[j][i].configure(bg='#F0F0F0')
374                         self.cv.itemconfigure(self.时间位总列表[j][i], fill='#FFFFFF')
375 
376     def 改变时间间隔(self, 偏移值):
377         def change_dtime(e):
378             if self.时间间隔 + 偏移值 > 0:
379                 self.时间间隔 += 偏移值
380             else:
381                 self.时间间隔 = 1
382             self.时间间隔描述标签.configure(text='时间间隔为: %d 分钟' % self.时间间隔)
383             self.刷新结果描述()
384         return change_dtime
385 
386     def 设置时间间隔(self, 设置值):
387         def set_dtime(e):
388             self.时间间隔 = 设置值
389             self.时间间隔描述标签.configure(text='时间间隔为: %d 分钟' % self.时间间隔)
390             self.刷新结果描述()
391 
392         return set_dtime
393 
394     def 刷新结果描述(self):
395         # print('刷新结果描述')
396         if self.选中的起始时间 and self.选中的结束时间:
397             # print(self.选中的起始时间)
398             第1个时间文本 = self.选中的起始时间.strftime('%Y年%m月%d日%H:%M')
399             第2个时间文本 = self.选中的结束时间.strftime('%Y年%m月%d日%H:%M')
400             if 第1个时间文本[:11] == 第2个时间文本[:11]:
401                 第2个时间文本 = 第2个时间文本[12:]
402             elif 第1个时间文本[:8] == 第2个时间文本[:8]:
403                 第2个时间文本 = 第2个时间文本[8:]
404             elif 第1个时间文本[:5] == 第2个时间文本[:5]:
405                 第2个时间文本 = 第2个时间文本[5:]
406             时间跨度 = self.选中的结束时间 - self.选中的起始时间
407             天数 = int(时间跨度.total_seconds() // (3600 * 24))
408             小时 = int(时间跨度.total_seconds() % (3600 * 24) // 3600)
409             分钟 = int(时间跨度.total_seconds() % 3600 // 60)
410             时间范围描述文本 = ''
411             if 天数 > 0:
412                 时间范围描述文本 += str(天数) + '天'
413             if 小时 > 0:
414                 时间范围描述文本 += str(小时) + '小时'
415             if 分钟 > 0:
416                 时间范围描述文本 += str(分钟) + '分钟'
417             时间间隔文本 = str(int(self.时间间隔))
418             生成记录条数 = int(时间跨度 / timedelta(minutes=self.时间间隔))
419             记录数量文本 = '预计生成%d条记录' % 生成记录条数
420             if 生成记录条数 > 19990:
421                 记录数量文本 += ',超出最大限制!!!'
422             self.cv.itemconfigure(self.选择结果描述标签, text='查询范围是%s到%s,共计%s,时间间隔%s分钟,%s' %
423                                                       (第1个时间文本,
424                                                        第2个时间文本,
425                                                        时间范围描述文本,
426                                                        时间间隔文本,
427                                                        记录数量文本))
428 
429     def 根据选择的时间点判断对应时间位的位置(self, 时间点):
430         # 时间点 = datetime.today()
431         时间偏移 = (时间点 - datetime.combine(self.时间区头, time())).total_seconds()
432         row = int(时间偏移 // (3600 * 24))
433         column = int(时间偏移 % (3600 * 24) // (10 * 60))
434         return row, column
435 
436     def run(self):
437         self.读取从机数据()
438         self.主窗口.mainloop()
439 
440     def close_win(self):
441         self.主窗口.destroy()
442 
443     def ok_action(self, e):
444         self.通讯器.写数据(0, [2])
445         self.通讯器.写数据(1, [7788])
446         if not self.选中的起始时间 or not self.选中的结束时间:
447             当前时间 = datetime.now()
448             分钟 = int(当前时间.minute // 10 * 10)
449             self.选中的结束时间 = datetime(当前时间.year,
450                                     当前时间.month,
451                                     当前时间.day,
452                                     当前时间.hour,
453                                     分钟)
454             self.选中的起始时间 = self.选中的结束时间 - timedelta(hours=2)
455         给组态王的起始时间 = self.转换为组态王时间(self.选中的起始时间)
456         给组态王的结束时间 = self.转换为组态王时间(self.选中的结束时间)
457         给组态王的时间间隔 = self.时间间隔 * 60
458         self.通讯器.写数据(2, self.转换为长整型(给组态王的起始时间))
459         self.通讯器.写数据(4, self.转换为长整型(给组态王的结束时间))
460         self.通讯器.写数据(6, self.转换为长整型(给组态王的时间间隔))
461         self.通讯器.写数据(8, [int(self.选中的起始时间.year)])
462         self.通讯器.写数据(9, [int(self.选中的起始时间.month)])
463         self.通讯器.写数据(10, [int(self.选中的起始时间.day)])
464         self.通讯器.写数据(11, [int(self.选中的起始时间.hour)])
465         self.通讯器.写数据(12, [int(self.选中的起始时间.minute)])
466         self.通讯器.写数据(13, [int(self.选中的结束时间.year)])
467         self.通讯器.写数据(14, [int(self.选中的结束时间.month)])
468         self.通讯器.写数据(15, [int(self.选中的结束时间.day)])
469         self.通讯器.写数据(16, [int(self.选中的结束时间.hour)])
470         self.通讯器.写数据(17, [int(self.选中的结束时间.minute)])
471         self.close_win()
472 
473     def 转换为长整型(self, 数据):
474         数据 = 数据 % (2 ** 31)
475         高16位 = int(数据 // (2 ** 16))
476         低16位 = int(abs(数据 % (2 ** 16)))
477         return [高16位, 低16位]
478 
479     def 转换为组态王时间(self, 时间点):
480         组态王时间 = 时间点 - datetime(1970, 1, 1, 8, 0, 0, 0)
481         # 组态王时间 = timedelta(seconds=0)
482         return 组态王时间.total_seconds()
483 
484     def 解码长整形(self, 字列表):
485         return int(字列表[0] * (2 ** 16) + 字列表[1])
486 
487     def 读取从机数据(self):
488         开始时间_组态王格式 = self.解码长整形(self.通讯器.读数据(2, 2))
489         结束时间_组态王格式 = self.解码长整形(self.通讯器.读数据(4, 2))
490         查询间隔_组态王格式 = self.解码长整形(self.通讯器.读数据(6, 2))
491         self.选中的起始时间 = datetime(1970, 1, 1, 8, 0, 0) + timedelta(seconds=开始时间_组态王格式)
492         self.选中的结束时间 = datetime(1970, 1, 1, 8, 0, 0) + timedelta(seconds=结束时间_组态王格式)
493         if 查询间隔_组态王格式 > 0:
494             self.时间间隔 = int(查询间隔_组态王格式 // 60)
495             self.时间间隔描述标签.configure(text='时间间隔为: %d 分钟' % self.时间间隔)
496         self.刷新结果描述()
497         self.刷新范围底色()
498 
499 
500 class modbus从机服务器():
501     def __init__(self):
502         # Create the server
503         self.server = modbus_tcp.TcpServer(address='127.0.0.1', port=9527)
504         self.server.start()
505         self.从机 = self.server.add_slave(1)
506         self.从机.add_block('0', cst.HOLDING_REGISTERS, 0, 100)
507 
508     def 关闭服务(self):
509         self.server.stop()
510 
511     def 写数据(self, 地址, 数据列表):
512         self.从机.set_values('0', 地址, 数据列表)
513 
514     def 读数据(self, 地址, 长度):
515         return self.从机.get_values('0', 地址, 长度)
516 
517 
518 if __name__ == '__main__':
519     从机 = modbus从机服务器()
520     日历选择控件 = 日历控件(从机)
521     # 日历选择控件.run()
522     while True:
523         # 从机.写数据(0, [5])
524         启动画面指令 = 从机.读数据(0, 1)[0]
525         # print(启动画面指令)
526         # print(type(启动画面指令))
527         if 启动画面指令 == 1:
528             日历选择控件.run()
529         if 启动画面指令 == 2:
530             日历选择控件 = 日历控件(从机)
531             从机.写数据(0, [0])
532         sleep(1)
View Code

依赖

链接:https://pan.baidu.com/s/1hNS7lQXIUSP34JzuU5gvgA?pwd=y62b
提取码:y62b

给懒汉的可执行文件

链接:https://pan.baidu.com/s/18n4FO4kiHDQDw0U2LCtcpg?pwd=bel7
提取码:bel7

 

标签:控件,python,self,组态王,日期,时间,坐标,按钮,间隔
From: https://www.cnblogs.com/jichao1515/p/17526881.html

相关文章

  • Python | yield关键字详解
    yield关键字的说明yield是Python中的一个关键字,它通常与生成器函数一起使用。yield就是保存当前程序执行状态。你用for循环的时候,每次取一个元素的时候就会计算一次。用yield的函数叫generator,和iterator一样,它的好处是不用一次计算所有元素,而是用一次算一次,可以节省......
  • python函数外变量传到函数内处理后不改变函数外的变量,copy模块使用
    线上代码a=[1,2,3]defabc(a):a.remove(1)abc(a)print(a)这段代码先指定了一个a变量是个list,又写了一个abc函数,功能是把外面传进来的list里面的1这个值去掉按理说在函数内的执行只应该属于函数内的变化,但是实际打印结果是[2,3],函数把外面变量的1删掉了这不是我想要......
  • python接口自动化封装导出excel方法和读写excel数据
    一、首先需要思考,我们在页面导出excel,用python导出如何写入文件的封装前需要确认python导出excel接口返回的是一个什么样的数据类型如下:我们先看下不对返回结果做处理,直接接收数据类型是一个对象,无法获取返回值此时我们需要对返回数据做处理,如下;response.text#响应文本数据......
  • Python 元组转换为列表
    1.直接将元组转为列表tup=(21,19,11,46,18)print(tup)lt=list(tup)print(lt)输出(21,19,11,46,18)[21,19,11,46,18]2.将元组列表转为列表#Listoftupleinitializationlistoftuples=[("Apple",1),("Microsoft",2),("Amazon",......
  • python计算某字符出现次数
    count()方法用于统计字符串里某个字符或子字符串出现的次数.st1=input().upper()st2=input().upper()print(st1.count(st2))tips:只要将所有字符串统一转化为大写或者小写,计算次数即可。upper()全部转化为大写lower()全部转化为小写另:str.count(sub,start=0,en......
  • Python中对open读取文件内容时的mode模式解析
    1.Python可以使用open函数来实现文件的打开,关闭,读写操作;Python3中的open函数定义为:open(file,mode='r',buffering=None,encoding=None,errors=None,newline=None,closefd=True)其中mode列表为:'r'#openforreading(default)'w'#openforwriting,truncatin......
  • vscode python开发环境搭建
    vscode是微软开发的轻量级ide软件,有大量的插件,很适合python开发。以下简述vscode的python开发环境搭建步骤:一、官网下载vscode软件基于安全考虑软件下载最好到官网下载。vscode官网地址:https://code.visualstudio.com/download,到2023年7月4日最新版本为:VSCodeUserSetup-x64-1.......
  • python基础day37 基于TCP、UDP协议的套接字编程和粘包现象
    基于TCP协议的套接字编程(socket编程)什么是Socket?我们经常把Socket翻译为套接字,Socket是在应用层和传输层之间的一个抽象层,它把TCO/IP层复杂的操作抽象为几个简单的接口供应用层调用以实现进程在网络中通信  套接字的分类:AF_UNIX:用在局域网中AF_INET:用在互联网中客户......
  • python中如何简洁剔除列表中的特定值
    在Python中,可以使用列表推导式或filter函数来剔除列表中的特定值。方法一:使用列表推导式original_list=[1,2,3,4,5]exclude_value=3new_list=[xforxinoriginal_listifx!=exclude_value]print(new_list)#输出:[1,2,4,5]方法二:使用filter函数origi......
  • pip安装python包到指定python版本下
    1.命令行进入到指定python安装目录。比如我电脑上有python3.8也有python3.9。准备给python3.9安装指定的包2.执行:python-mpipinstall包名......