yut 0.2.20__py2.py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (207) hide show
  1. yui/__init__.py +608 -0
  2. yui/images/ico/airplane.ico +0 -0
  3. yui/images/ico/calc.ico +0 -0
  4. yui/images/ico/circle_cube2.ico +0 -0
  5. yui/images/ico/dcube.ico +0 -0
  6. yui/images/ico/fap.ico +0 -0
  7. yui/images/ico/ndas.ico +0 -0
  8. yui/images/ico/ndw.ico +0 -0
  9. yui/images/png/3_.png +0 -0
  10. yui/images/png/3dots_h.png +0 -0
  11. yui/images/png/3dots_v.png +0 -0
  12. yui/images/png/3i.png +0 -0
  13. yui/images/png/4_dots.png +0 -0
  14. yui/images/png/4_square.png +0 -0
  15. yui/images/png/add_subs.png +0 -0
  16. yui/images/png/addgreen.png +0 -0
  17. yui/images/png/appicon.png +0 -0
  18. yui/images/png/ar_arrow.png +0 -0
  19. yui/images/png/ar_check.png +0 -0
  20. yui/images/png/arrow_cursor.png +0 -0
  21. yui/images/png/attach.png +0 -0
  22. yui/images/png/back.png +0 -0
  23. yui/images/png/ball.png +0 -0
  24. yui/images/png/ball2.png +0 -0
  25. yui/images/png/ball_blue.png +0 -0
  26. yui/images/png/ball_bullet.png +0 -0
  27. yui/images/png/ball_darkred.png +0 -0
  28. yui/images/png/ball_golden.png +0 -0
  29. yui/images/png/ball_green.png +0 -0
  30. yui/images/png/ball_light.png +0 -0
  31. yui/images/png/ball_red.png +0 -0
  32. yui/images/png/biz_1.png +0 -0
  33. yui/images/png/biz_2.png +0 -0
  34. yui/images/png/blue_star.png +0 -0
  35. yui/images/png/bulb.png +0 -0
  36. yui/images/png/bullet1.png +0 -0
  37. yui/images/png/bullet1_golden.png +0 -0
  38. yui/images/png/bullet2.png +0 -0
  39. yui/images/png/bullet2_golden.png +0 -0
  40. yui/images/png/bullet3.png +0 -0
  41. yui/images/png/bullet3_golden.png +0 -0
  42. yui/images/png/bullet4.png +0 -0
  43. yui/images/png/calc.png +0 -0
  44. yui/images/png/calendar.png +0 -0
  45. yui/images/png/cancel.png +0 -0
  46. yui/images/png/chart.png +0 -0
  47. yui/images/png/chart_bar.png +0 -0
  48. yui/images/png/chart_line.png +0 -0
  49. yui/images/png/chart_linebar.png +0 -0
  50. yui/images/png/chart_pie.png +0 -0
  51. yui/images/png/chat.png +0 -0
  52. yui/images/png/check.png +0 -0
  53. yui/images/png/check_sheet.png +0 -0
  54. yui/images/png/circle_cube.png +0 -0
  55. yui/images/png/circle_cube2.png +0 -0
  56. yui/images/png/clip_board.png +0 -0
  57. yui/images/png/close.png +0 -0
  58. yui/images/png/close_x.png +0 -0
  59. yui/images/png/continue.png +0 -0
  60. yui/images/png/contract.png +0 -0
  61. yui/images/png/contract_2.png +0 -0
  62. yui/images/png/cube4.png +0 -0
  63. yui/images/png/custom.png +0 -0
  64. yui/images/png/custom_care.png +0 -0
  65. yui/images/png/custom_money.png +0 -0
  66. yui/images/png/db.png +0 -0
  67. yui/images/png/dcube.png +0 -0
  68. yui/images/png/diamond.png +0 -0
  69. yui/images/png/doc.png +0 -0
  70. yui/images/png/doc2.png +0 -0
  71. yui/images/png/doc_percent.png +0 -0
  72. yui/images/png/doc_rpt.png +0 -0
  73. yui/images/png/download.png +0 -0
  74. yui/images/png/download_2.png +0 -0
  75. yui/images/png/drop.png +0 -0
  76. yui/images/png/earth.png +0 -0
  77. yui/images/png/exec_all.png +0 -0
  78. yui/images/png/execute.png +0 -0
  79. yui/images/png/export.png +0 -0
  80. yui/images/png/eye.png +0 -0
  81. yui/images/png/fangsheng.png +0 -0
  82. yui/images/png/fapicon.png +0 -0
  83. yui/images/png/filter.png +0 -0
  84. yui/images/png/fit_width.png +0 -0
  85. yui/images/png/fly_up.png +0 -0
  86. yui/images/png/forward.png +0 -0
  87. yui/images/png/func.png +0 -0
  88. yui/images/png/func_group.png +0 -0
  89. yui/images/png/func_item.png +0 -0
  90. yui/images/png/function.png +0 -0
  91. yui/images/png/gauge.png +0 -0
  92. yui/images/png/goal.png +0 -0
  93. yui/images/png/golden_star.png +0 -0
  94. yui/images/png/green_star.png +0 -0
  95. yui/images/png/grid.png +0 -0
  96. yui/images/png/grid_1.png +0 -0
  97. yui/images/png/grid_cube.png +0 -0
  98. yui/images/png/gridview.png +0 -0
  99. yui/images/png/hand.png +0 -0
  100. yui/images/png/heart.png +0 -0
  101. yui/images/png/hexstar.png +0 -0
  102. yui/images/png/home.png +0 -0
  103. yui/images/png/html.png +0 -0
  104. yui/images/png/index.png +0 -0
  105. yui/images/png/inout.png +0 -0
  106. yui/images/png/join.png +0 -0
  107. yui/images/png/key.png +0 -0
  108. yui/images/png/label.png +0 -0
  109. yui/images/png/label_2.png +0 -0
  110. yui/images/png/last.png +0 -0
  111. yui/images/png/left.png +0 -0
  112. yui/images/png/left2.png +0 -0
  113. yui/images/png/levels.png +0 -0
  114. yui/images/png/lightning.png +0 -0
  115. yui/images/png/link.png +0 -0
  116. yui/images/png/lock.png +0 -0
  117. yui/images/png/logo.png +0 -0
  118. yui/images/png/lookup.png +0 -0
  119. yui/images/png/loop.png +0 -0
  120. yui/images/png/max.png +0 -0
  121. yui/images/png/mblocks.png +0 -0
  122. yui/images/png/milestone.png +0 -0
  123. yui/images/png/min.png +0 -0
  124. yui/images/png/minus.png +0 -0
  125. yui/images/png/money_forward.png +0 -0
  126. yui/images/png/more.png +0 -0
  127. yui/images/png/multi_block.png +0 -0
  128. yui/images/png/next.png +0 -0
  129. yui/images/png/notebook.png +0 -0
  130. yui/images/png/nstc.png +0 -0
  131. yui/images/png/off.png +0 -0
  132. yui/images/png/okr.png +0 -0
  133. yui/images/png/open.png +0 -0
  134. yui/images/png/org.png +0 -0
  135. yui/images/png/org1.png +0 -0
  136. yui/images/png/org2.png +0 -0
  137. yui/images/png/outcome.png +0 -0
  138. yui/images/png/paper_plane.png +0 -0
  139. yui/images/png/parts.png +0 -0
  140. yui/images/png/pause.png +0 -0
  141. yui/images/png/pc.png +0 -0
  142. yui/images/png/pc_bar.png +0 -0
  143. yui/images/png/person_card.png +0 -0
  144. yui/images/png/person_chart.png +0 -0
  145. yui/images/png/person_doc.png +0 -0
  146. yui/images/png/person_fire.png +0 -0
  147. yui/images/png/person_hire.png +0 -0
  148. yui/images/png/pie.png +0 -0
  149. yui/images/png/pie_2.png +0 -0
  150. yui/images/png/play.png +0 -0
  151. yui/images/png/plus.png +0 -0
  152. yui/images/png/red_star.png +0 -0
  153. yui/images/png/refresh.png +0 -0
  154. yui/images/png/report.png +0 -0
  155. yui/images/png/revert.png +0 -0
  156. yui/images/png/right.png +0 -0
  157. yui/images/png/right2.png +0 -0
  158. yui/images/png/right_3.png +0 -0
  159. yui/images/png/save.png +0 -0
  160. yui/images/png/save_data.png +0 -0
  161. yui/images/png/setting.png +0 -0
  162. yui/images/png/show_normal.png +0 -0
  163. yui/images/png/site.png +0 -0
  164. yui/images/png/site_blue.png +0 -0
  165. yui/images/png/sort.png +0 -0
  166. yui/images/png/star.png +0 -0
  167. yui/images/png/stop.png +0 -0
  168. yui/images/png/sum.png +0 -0
  169. yui/images/png/sum_1.png +0 -0
  170. yui/images/png/target.png +0 -0
  171. yui/images/png/time.png +0 -0
  172. yui/images/png/to_cloud.png +0 -0
  173. yui/images/png/todo.png +0 -0
  174. yui/images/png/tools.png +0 -0
  175. yui/images/png/tree.png +0 -0
  176. yui/images/png/trush.png +0 -0
  177. yui/images/png/tumber.png +0 -0
  178. yui/images/png/turn_up.png +0 -0
  179. yui/images/png/two_persons.png +0 -0
  180. yui/images/png/user.png +0 -0
  181. yui/images/png/var.png +0 -0
  182. yui/images/png/view.png +0 -0
  183. yui/images/png/vv_down.png +0 -0
  184. yui/images/png/vvv_down.png +0 -0
  185. yui/images.qrc +189 -0
  186. yui/images_rc.py +138253 -0
  187. yui/img.py +185 -0
  188. yui/qrc_tools.py +54 -0
  189. yui/wdg.py +1688 -0
  190. yui/ydict.py +95 -0
  191. yui/yfield.py +1268 -0
  192. yui/yform.py +205 -0
  193. yui/ylookup.py +329 -0
  194. yui/ymodel.py +516 -0
  195. yui/ystat.py +1278 -0
  196. yui/ytable.py +648 -0
  197. yui/ytree.py +102 -0
  198. yus/__init__.py +196 -0
  199. yus/dbm.py +721 -0
  200. yut/__init__.py +558 -0
  201. yut/asynx.py +250 -0
  202. yut/mes.py +206 -0
  203. yut/rmi.py +196 -0
  204. yut/win32.py +260 -0
  205. yut-0.2.20.dist-info/METADATA +297 -0
  206. yut-0.2.20.dist-info/RECORD +207 -0
  207. yut-0.2.20.dist-info/WHEEL +4 -0
yui/__init__.py ADDED
@@ -0,0 +1,608 @@
1
+ # -*- yui.py: python ; coding: utf-8 -*-
2
+ # 基于PySide开发的通用GUI工具
3
+ import sys
4
+ from enum import Enum
5
+
6
+ from PySide6.QtCore import Qt, Signal, QSize, QEvent
7
+ from PySide6.QtGui import (QIcon, QColor, QEnterEvent, QPalette, QPixmap, QAction)
8
+ from PySide6.QtWidgets import (QApplication, QToolBar, QWidget, QPushButton, QToolButton, QSizePolicy,
9
+ QLayout, QHBoxLayout, QVBoxLayout, QGridLayout, QFormLayout, QDateTimeEdit,
10
+ QCalendarWidget, QGroupBox, QFileDialog, QDateEdit, QMenu)
11
+ from PySide6.QtWidgets import (QMessageBox)
12
+
13
+ from yut import get_attr, is_execute_able, call_exp
14
+ from yut.win32 import set_process_user_model_id
15
+
16
+
17
+ class Theme(Enum):
18
+ DARK = '深色'
19
+ LIGHT = '浅色'
20
+
21
+ def icon_color(self):
22
+ return {self.DARK: QColor(100, 149, 237),
23
+ self.LIGHT: QColor(80, 128, 218), }.get(self)
24
+
25
+ def hover_color(self):
26
+ return {self.DARK: QColor(80, 140, 242),
27
+ self.LIGHT: QColor(80, 120, 226), }.get(self)
28
+
29
+ def hi_light_color(self):
30
+ return {self.DARK: QColor(212, 212, 212),
31
+ self.LIGHT: QColor(212, 212, 30), }.get(self)
32
+
33
+ def enforce_color(self):
34
+ return {self.DARK: QColor(192, 168, 32),
35
+ self.LIGHT: QColor(16, 12, 30), }.get(self)
36
+
37
+
38
+ class HoveredButton(QPushButton):
39
+ entered = Signal()
40
+ leaved = Signal()
41
+
42
+ def enterEvent(self, event: QEnterEvent) -> None:
43
+ super().enterEvent(event)
44
+ self.entered.emit()
45
+
46
+ def leaveEvent(self, event: QEvent) -> None:
47
+ super().leaveEvent(event)
48
+ self.leaved.emit()
49
+
50
+
51
+ class HoveredToolButton(QToolButton):
52
+ entered = Signal()
53
+ leaved = Signal()
54
+
55
+ def enterEvent(self, event: QEnterEvent) -> None:
56
+ super().enterEvent(event)
57
+ self.entered.emit()
58
+
59
+ def leaveEvent(self, event: QEvent) -> None:
60
+ super().leaveEvent(event)
61
+ self.leaved.emit()
62
+
63
+
64
+ current_theme = Theme.DARK
65
+
66
+
67
+ def set_current_theme(theme: Theme):
68
+ global current_theme
69
+ current_theme = theme
70
+
71
+
72
+ def create_default_app(argv=None, theme: Theme = Theme.DARK, app_name=None, icon_file=None) -> QApplication:
73
+ import yui.images_rc as images
74
+ import qtmodern.styles as style
75
+ arv = argv if argv is not None else sys.argv
76
+ app = QApplication(arv)
77
+ if app_name:
78
+ set_process_user_model_id(app_name)
79
+ app.setApplicationDisplayName(app_name)
80
+ app.setApplicationName(app_name)
81
+ if icon_file:
82
+ app.setWindowIcon(load_icon(icon_file, colored=False))
83
+ set_current_theme(theme)
84
+ if theme == Theme.DARK:
85
+ style.dark(app)
86
+ else:
87
+ style.light(app)
88
+ return app
89
+
90
+
91
+ def get_app() -> QApplication | None:
92
+ return QApplication.instance()
93
+
94
+
95
+ def get_mainwindow() -> QWidget | None:
96
+ app = get_app()
97
+ if hasattr(app, 'main_window'):
98
+ return app.main_window
99
+ else:
100
+ return app.activeWindow()
101
+
102
+
103
+ def get_active_window() -> QWidget | None:
104
+ app = get_app()
105
+ return app.activeWindow() if app else None
106
+
107
+
108
+ def colored_pixmap(file_name, colored=True):
109
+ pix = QPixmap(file_name)
110
+ if colored:
111
+ mask = pix.createMaskFromColor(Qt.GlobalColor.transparent)
112
+ color = current_theme.icon_color() # QPalette().color(QPalette.Highlight) # theme_icon_color
113
+ pix.fill(color)
114
+ pix.setMask(mask)
115
+ return pix
116
+
117
+
118
+ def load_icon(file_name, colored=True):
119
+ return QIcon(colored_pixmap(file_name, colored=colored))
120
+
121
+
122
+ def create_action(text, trigger, icon_file=None, parent=None, object_name=None) -> QAction:
123
+ action = QAction(load_icon(icon_file), text, parent)
124
+ action.triggered.connect(trigger)
125
+ action.setObjectName(object_name)
126
+ return action
127
+
128
+
129
+ def create_button(text='', trigger=None, icon=None, icon_file=None, flat=None, tip_text=None, parent=None,
130
+ object_name=None, icon_only=False,
131
+ icon_size: QSize | int = None, ):
132
+ btn = QPushButton(text if not icon_only else '', parent=parent)
133
+ btn.setObjectName(object_name)
134
+ if icon:
135
+ btn.setIcon(icon)
136
+ else:
137
+ if icon_file:
138
+ btn.setIcon(load_icon(icon_file))
139
+ if flat is not None:
140
+ btn.setFlat(flat)
141
+ if tip_text is not None:
142
+ btn.setToolTip(tip_text)
143
+ else:
144
+ if text:
145
+ btn.setToolTip(text)
146
+ if trigger:
147
+ btn.clicked.connect(trigger)
148
+ if icon_size:
149
+ size = icon_size if isinstance(icon_size, QSize) else QSize(icon_size, icon_size)
150
+ btn.setIconSize(size)
151
+ btn.setIconSize(QSize(icon_size, icon_size))
152
+ return btn
153
+
154
+
155
+ def create_tool_button(text='',
156
+ trigger=None,
157
+ icon=None,
158
+ icon_file=None,
159
+ tip_text=None,
160
+ parent=None,
161
+ icon_size: QSize | int = None,
162
+ button_style=Qt.ToolButtonStyle.ToolButtonIconOnly,
163
+ flat=False,
164
+ object_name=None,
165
+ ) -> QToolButton:
166
+ btn = QToolButton(parent=parent)
167
+ btn.setToolButtonStyle(button_style)
168
+ btn.setObjectName(object_name)
169
+ if text:
170
+ btn.setText(text)
171
+ if icon:
172
+ btn.setIcon(icon)
173
+ else:
174
+ if icon_file:
175
+ btn.setIcon(load_icon(icon_file))
176
+ if tip_text is not None:
177
+ btn.setToolTip(tip_text)
178
+ else:
179
+ if text:
180
+ btn.setToolTip(text)
181
+ if trigger:
182
+ btn.clicked.connect(trigger)
183
+ if icon_size:
184
+ size = icon_size if isinstance(icon_size, QSize) else QSize(icon_size, icon_size)
185
+ btn.setIconSize(size)
186
+ if flat:
187
+ btn.setStyleSheet("border - style: flat; background: transparent;")
188
+ # btn.setFocusPolicy(Qt.FocusPolicy.NoFocus)
189
+ return btn
190
+
191
+
192
+ def create_menu_button(menu: QMenu,
193
+ title=None,
194
+ icon_file=None,
195
+ icon=None,
196
+ hovered=False,
197
+ icon_size: QSize | int = None,
198
+ tool_button=False,
199
+ indicator=False,
200
+ object_name=None) -> HoveredButton | HoveredToolButton | QToolButton | QPushButton:
201
+ if icon_size is not None:
202
+ size = icon_size if isinstance(icon_size, QSize) else QSize(icon_size, icon_size)
203
+ else:
204
+ size = QSize(14, 14)
205
+
206
+ if hovered:
207
+ if tool_button:
208
+ btn = HoveredToolButton()
209
+ btn.setSizePolicy(QSizePolicy(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Fixed))
210
+ btn.setPopupMode(QToolButton.ToolButtonPopupMode.InstantPopup)
211
+ else:
212
+ btn = HoveredButton()
213
+ btn.setFlat(True)
214
+ btn.entered.connect(btn.click)
215
+ else:
216
+ if tool_button:
217
+ btn = QToolButton()
218
+ btn.setPopupMode(QToolButton.ToolButtonPopupMode.InstantPopup)
219
+ else:
220
+ btn = QPushButton()
221
+ btn.setFlat(True)
222
+
223
+ btn.setSizePolicy(QSizePolicy(QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Fixed))
224
+
225
+ if not indicator: # 去掉menu指引箭头
226
+ if isinstance(btn, QToolButton):
227
+ btn.setStyleSheet('QToolButton::menu-indicator {image: none;}')
228
+ if isinstance(btn, QPushButton):
229
+ btn.setStyleSheet('QPushButton::menu-indicator {image: none;}')
230
+
231
+ btn.setMenu(menu)
232
+ btn.setIconSize(size)
233
+ btn.setObjectName(object_name)
234
+
235
+ if title:
236
+ btn.setText(title)
237
+ btn.setToolTip(title)
238
+
239
+ if icon:
240
+ btn.setIcon(icon)
241
+ elif icon_file:
242
+ btn.setIcon(load_icon(icon_file))
243
+
244
+ return btn
245
+
246
+
247
+ def create_toolbar(buttons=None, actions=None, icon_size=12, parent=None, object_name=None) -> QToolBar:
248
+ tbar = QToolBar(parent=parent)
249
+ tbar.setIconSize(QSize(icon_size, icon_size))
250
+ tbar.setObjectName(object_name)
251
+ if actions:
252
+ tbar.addActions(actions)
253
+ if buttons:
254
+ if actions:
255
+ tbar.addSeparator()
256
+ for btn in buttons:
257
+ tbar.addWidget(btn)
258
+ return tbar
259
+
260
+
261
+ def pop_info(*args, title=None, sep=' '):
262
+ text = sep.join([str(a) for a in args])
263
+ if not title:
264
+ title = '提示信息'
265
+ QMessageBox.information(get_mainwindow(), title, text)
266
+
267
+
268
+ def pop_question(*args, title=None, sep=' '):
269
+ text = sep.join([str(a) for a in args])
270
+ if not title:
271
+ title = '请确认信息'
272
+ return QMessageBox.question(get_mainwindow(), title, text,
273
+ QMessageBox.StandardButton.Ok,
274
+ QMessageBox.StandardButton.Cancel) == QMessageBox.StandardButton.Ok
275
+
276
+
277
+ def pop_warning(*args, title=None, sep=' '):
278
+ text = sep.join([str(a) for a in args])
279
+ if not title:
280
+ title = '提示信息'
281
+ QMessageBox.warning(get_mainwindow(), title, text)
282
+
283
+
284
+ def load_style_sheet(fname):
285
+ style = ''
286
+ for line in open(fname, encoding='utf-8').readlines():
287
+ style += line
288
+ get_app().setStyleSheet(style)
289
+
290
+
291
+ def contrast_color(color):
292
+ luminance = (0.299 * color.red() + 0.587 * color.green() + 0.114 * color.blue()) / 255
293
+ # luminance = (color.red() + color.green() + color.blue()) / (3 * 255)
294
+ if luminance > 0.5:
295
+ contrast = QColor('#000000')
296
+ else:
297
+ contrast = QColor('#FFFFFF')
298
+ return contrast
299
+
300
+
301
+ def change_font(w, bold=None, size=None, italic=None, underline=None, strike=None):
302
+ font = w.font()
303
+ if bold is not None:
304
+ font.setBold(bold)
305
+ if underline is not None:
306
+ font.setUnderline(underline)
307
+ if italic is not None:
308
+ font.setItalic(italic)
309
+ if strike is not None:
310
+ font.setStrike(strike)
311
+ if size:
312
+ font.setPointSize(size)
313
+ w.setFont(font)
314
+ return w
315
+
316
+
317
+ def change_item_display(item, bold=None, italic=None, underline=None, strike=None, size=None, color=None,
318
+ background=None):
319
+ font = item.font()
320
+ if bold is not None:
321
+ font.setBold(bold)
322
+ if size:
323
+ font.setPointSize(size)
324
+ if underline is not None:
325
+ font.setUnderline(underline)
326
+ if italic is not None:
327
+ font.setItalic(italic)
328
+ if strike is not None:
329
+ font.setStrike(strike)
330
+ item.setFont(font)
331
+
332
+ if color:
333
+ item.setForeground(color)
334
+ if background:
335
+ item.setBackground(background)
336
+ return item
337
+
338
+
339
+ def set_label_color(lb, bk_color=None, fore_color=None):
340
+ pe = QPalette()
341
+ if bk_color:
342
+ lb.setAutoFillBackground(True)
343
+ pe.setColor(QPalette.ColorRole.Window, bk_color)
344
+ if fore_color:
345
+ pe.setColor(QPalette.ColorRole.WindowText, fore_color)
346
+ lb.setPalette(pe)
347
+ return lb
348
+
349
+
350
+ def set_widget_color(wdg, bk_color=None, fore_color=None):
351
+ palette = wdg.palette()
352
+ if bk_color:
353
+ palette.setColor(QPalette.ColorRole.Window, bk_color)
354
+ if fore_color:
355
+ palette.setColor(QPalette.ColorRole.Text, fore_color)
356
+ wdg.setPalette(palette)
357
+
358
+
359
+ def create_layout(layout_flag='H', parent=None,
360
+ object_name=None) -> QHBoxLayout | QVBoxLayout | QGridLayout | QFormLayout:
361
+ """
362
+ 依据标记创建布局对象
363
+ :param object_name:
364
+ :param parent:
365
+ :param layout_flag:
366
+ 'H' - HBox ;
367
+ 'V' - VBox ;
368
+ 'F' - FormLayout ;
369
+ 'G##' - GridLayout 紧跟在G后面的是Grid布局的列数目,如'G3'表示创建表格布局,每行3列,会将列数加到布局回想的column_num属性中
370
+ :return: QLayout 对象,如果是GridLayout,增加column_num属性,保存打算布置的列数
371
+ """
372
+ if layout_flag == 'V':
373
+ lyt = QVBoxLayout()
374
+ lyt.setAlignment(Qt.AlignmentFlag.AlignLeft)
375
+ lyt.setSpacing(4)
376
+ elif layout_flag.startswith('G'):
377
+ lyt = QGridLayout()
378
+ if len(layout_flag) > 1:
379
+ lyt.column_num = int(layout_flag[1:])
380
+ lyt.setHorizontalSpacing(4)
381
+ lyt.setVerticalSpacing(4)
382
+ elif layout_flag == 'F':
383
+ lyt = QFormLayout()
384
+ lyt.setAlignment(Qt.AlignmentFlag.AlignTop)
385
+ lyt.setLabelAlignment(
386
+ Qt.AlignmentFlag.AlignRight | Qt.AlignmentFlag.AlignTrailing | Qt.AlignmentFlag.AlignVCenter)
387
+ lyt.setFormAlignment(Qt.AlignmentFlag.AlignLeading | Qt.AlignmentFlag.AlignLeft | Qt.AlignmentFlag.AlignVCenter)
388
+ lyt.setHorizontalSpacing(16)
389
+ lyt.setVerticalSpacing(16)
390
+ else:
391
+ lyt = QHBoxLayout()
392
+ lyt.setAlignment(Qt.AlignmentFlag.AlignVCenter)
393
+ lyt.setSpacing(4)
394
+ lyt.setContentsMargins(0, 0, 0, 0)
395
+ lyt.setParent(parent)
396
+ lyt.setObjectName(object_name)
397
+ return lyt
398
+
399
+
400
+ def create_widget(target=QWidget, parent=None, object_name=None) -> QWidget:
401
+ """
402
+ 创建QWidget
403
+ :param object_name:
404
+ :param target: 可以是QWidget实例/QWidget class及其子类/函数/表达式,默认为QWidget class
405
+ :param parent:
406
+ :return:
407
+ """
408
+ import inspect
409
+ widget = None
410
+ if isinstance(target, QWidget):
411
+ widget = target
412
+ elif inspect.isclass(target):
413
+ widget = target(parent=parent)
414
+ elif is_execute_able(target):
415
+ widget = target()
416
+ elif isinstance(target, str):
417
+ widget = call_exp(target)
418
+ if parent and widget:
419
+ widget.setParent(parent)
420
+ widget.setObjectName(object_name)
421
+ return widget
422
+
423
+
424
+ def create_layout_widget(target=QWidget, parent=None, layout_flag='H', object_name=None, window_title=None) -> QWidget:
425
+ """
426
+ 创建带布局的widget,并将布局设置为widget的主布局
427
+ :param target: Widget类,默认使用QWidget
428
+ :param layout_flag:
429
+ 'H' - HBox ;
430
+ 'V' - VBox ;
431
+ 'F' - FormLayout ;
432
+ 'G##' - GridLayout 紧跟在G后面的是Grid布局的列数目,如'G3'表示创建表格布局,每行3列,会将列数加到布局回想的column_num属性中
433
+ :param parent: 创建widget时使用的父对象
434
+ :param object_name: 对象名,setObjectName
435
+ :param window_title: 窗口标题,setWindowTitle
436
+ :return: QWidget
437
+ """
438
+ widget = create_widget(target, parent=parent)
439
+ widget.setLayout(create_layout(layout_flag))
440
+ widget.setObjectName(object_name)
441
+ if window_title:
442
+ widget.setWindowTitle(window_title)
443
+ return widget
444
+
445
+
446
+ def set_layout_spacing(lyt, h_spacing=0, v_spacing=0):
447
+ if isinstance(lyt, QHBoxLayout):
448
+ lyt.setSpacing(h_spacing)
449
+ elif isinstance(lyt, QVBoxLayout):
450
+ lyt.setSpacing(v_spacing)
451
+ elif isinstance(lyt, QGridLayout):
452
+ lyt.setHorizontalSpacing(h_spacing)
453
+ lyt.setVerticalSpacing(v_spacing)
454
+ elif isinstance(lyt, QFormLayout):
455
+ lyt.setHorizontalSpacing(h_spacing)
456
+ lyt.setVerticalSpacing(v_spacing)
457
+
458
+
459
+ def clear_layout(layout: QLayout):
460
+ for i in range(layout.count() - 1, -1, -1):
461
+ item = layout.itemAt(i)
462
+ if item.widget():
463
+ item.widget().deleteLater()
464
+ layout.removeItem(item)
465
+
466
+
467
+ def show_in_center(widget):
468
+ screen_rect = get_app().primaryScreen().geometry()
469
+ widget.setGeometry(screen_rect.width() // 2 - widget.width() // 2,
470
+ screen_rect.height() // 2 - widget.height() // 2,
471
+ widget.width(),
472
+ widget.height())
473
+ widget.show()
474
+
475
+
476
+ def create_date_edit(date, parent=None, object_name=None) -> QDateEdit:
477
+ edt = QDateTimeEdit(date, parent=parent)
478
+ edt.setObjectName(object_name)
479
+ edt.setCalendarPopup(True)
480
+ edt.setDisplayFormat('yyyy-MM-dd')
481
+ edt.setMinimumWidth(100)
482
+ w = QCalendarWidget(edt)
483
+ w.setGridVisible(True)
484
+ w.setAutoFillBackground(True)
485
+ w.setObjectName('dateEditCalendar')
486
+ w.setMinimumWidth(200)
487
+ w.setMaximumHeight(300)
488
+ edt._cal_widget = w
489
+ edt.setCalendarWidget(edt._cal_widget)
490
+ return edt
491
+
492
+
493
+ def filename_for_save(path='.', caption=None, file_filter='*.*'):
494
+ caption = caption if not caption else '请选择待保存的文件位置'
495
+ dlg = QFileDialog(parent=None, caption=caption)
496
+ files = dlg.getSaveFileName(parent=None, caption=caption, dir=path, filter=file_filter)
497
+ if files[0]:
498
+ return files[0]
499
+ else:
500
+ return None
501
+
502
+
503
+ def add_to_layout(layout: QLayout, widget: QWidget | QLayout, index=-1):
504
+ if index < 0:
505
+ attr = 'addWidget' if isinstance(widget, QWidget) else 'addLayout'
506
+ else:
507
+ attr = 'insertWidget' if isinstance(widget, QWidget) else 'insertLayout'
508
+ fn_add = get_attr(layout, attr)
509
+ if isinstance(layout, QGridLayout): # Grid布局
510
+ n_count = layout.count()
511
+ if hasattr(layout, 'column_num'):
512
+ column_num = get_attr(layout, 'column_num', 2)
513
+ fn_add(widget, n_count / column_num, n_count % column_num)
514
+ else: # HBox | VBox |GroupBox
515
+ if index < 0:
516
+ fn_add(widget)
517
+ else:
518
+ fn_add(index, widget)
519
+
520
+
521
+ def add_field(layout: QLayout, field: QWidget, label=None, index=-1):
522
+ """
523
+ 在布局中添加部件。如果是FormLayout,要求label为QWidget使用addRow
524
+ :param index: -1 - add; >=0 - insert
525
+ :param layout:
526
+ :param field:
527
+ :param label:
528
+ :return:
529
+ """
530
+ if isinstance(layout, QFormLayout): # Form布局
531
+ layout.addRow(label, field)
532
+ else:
533
+ w = field
534
+ if label is not None: # 创建组合框,否则直接在layout中增加
535
+ g_box = QGroupBox(field.parent())
536
+ g_box.setLayout(QVBoxLayout())
537
+ g_box.layout().setContentsMargins(0, 0, 0, 0)
538
+ g_box.layout().addWidget(field)
539
+ g_box.setTitle(label)
540
+ w = g_box
541
+ add_to_layout(layout, w, index)
542
+
543
+
544
+ class WorkMode(Enum):
545
+ """
546
+ 单元的工作模式,显示/编辑
547
+ """
548
+ DISPLAY = 0 # 显示模式
549
+ EDIT = 1 # 编辑模式
550
+ WATCH = 2 # 监视模式 - 只读显示,但该字段在其它地方改变之后需要更新
551
+
552
+
553
+ class EditMode(Enum):
554
+ """
555
+ 表单/列表的编辑模式,新增/修改
556
+ """
557
+ NEW = 0 # 新增
558
+ MODIFY = 1 # 修改
559
+
560
+
561
+ class Stage(Enum):
562
+ """
563
+ 单元的使用场景
564
+ """
565
+ IN_FORM = 0 # 表单式
566
+ IN_TABLE = 1 # 列表式
567
+ IN_QUERY = 2 # 查询条件
568
+
569
+
570
+ class TranslateDirection(Enum):
571
+ TO_TEXT = 0 # 值 -> 显示文字
572
+ TO_VALUE = 1 # 显示文字 -> 值
573
+
574
+
575
+ class LookupViewType(Enum):
576
+ """
577
+ LookupView类型
578
+ """
579
+ List = 0 # 列表: 无表头,无查询条件,可以筛选
580
+ Table = 1 # 表格: 有表头,可以多列,可以带查询条件以及点击排序
581
+ Tree = 2 # 树:有表头,可以多列,树形展开,无查询条件录入框
582
+
583
+
584
+ def alignment_flag(tag):
585
+ """
586
+ :param tag:
587
+ '>' - 右对齐
588
+ '|' - 水平居中
589
+ '<' - 左对齐
590
+ '^' - 顶对齐
591
+ '-' - 垂直居中
592
+ '_' - 底对齐
593
+ :return:
594
+ """
595
+ horizontal_alignment, vertical_alignment = Qt.AlignmentFlag.AlignCenter, Qt.AlignmentFlag.AlignVCenter
596
+ for ch, h_flag in {'>': Qt.AlignmentFlag.AlignRight,
597
+ '<': Qt.AlignmentFlag.AlignLeft,
598
+ '|': Qt.AlignmentFlag.AlignCenter
599
+ }.items():
600
+ if ch in tag:
601
+ horizontal_alignment = h_flag
602
+ for ch, v_flag in {'^': Qt.AlignmentFlag.AlignTop,
603
+ '_': Qt.AlignmentFlag.AlignBottom,
604
+ '-': Qt.AlignmentFlag.AlignVCenter
605
+ }.items():
606
+ if ch in tag:
607
+ vertical_alignment = v_flag
608
+ return horizontal_alignment | vertical_alignment
Binary file
Binary file
Binary file
Binary file
yui/images/ico/fap.ico ADDED
Binary file
Binary file
yui/images/ico/ndw.ico ADDED
Binary file
yui/images/png/3_.png ADDED
Binary file
Binary file
Binary file
yui/images/png/3i.png ADDED
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file