PyQt5设计思路(长期更新,每写一篇新博客都会更新一次)
PyQt5设计思路(长期更新,每写⼀篇新博客都会更新⼀次)概述
  ⽬前有关于PyQt5的系统的教程较少,毕竟Python的主要⽤途也不是做图形界⾯。但是鉴于作者最近想将很多的感兴趣的研究成果打包到⼀个应⽤⾥展⽰,⽽这些成果移植到Python会具有很强的可读性,所以就产⽣了⽤PyQt5来做GUI的念头。不过作者虽然听说Python的⼤名很多年,但是认真的⽤Python做⼀个稍复杂规模的应⽤还是第⼀回,制作过程中很多地⽅都是参考⽤其他语⾔做GUI Projct的经验和
Qt(C++)的官⽅⽂档,或者⼲脆⾃⼰摸索出来的。
本应⽤是作者秉持“可扩展+最⼤程度降低重复代码”的理念制作完成的。
设计⽬标
  为了便于后续对代码的修改管理,在设计最初就应该定好⼀个合理的框架。为了做到这点,作者个⼈认为有以下⼏点是必须要遵守的。
1)    禁⽌组件的个性化命名。这点是很重要的,虽然将某个按钮按照它调⽤的函数来做相关的命名后,在Debug的时候是很容易修正⼀些逻辑设计上的问题的。但是当应⽤越做越⼤的时候,个性化的命名会“锁住”你的设计框架,从⽽在⼈们想要修改设计思路的时候,感到如陷泥沼般的困难。
2)    设计⼀个函数来批量的”new”你的组件,将你的组件和数据统⼀放到⼀个“容器”⾥,对组件和数据来说这个容器是字典较为合适,⽽字典的最底层往往是⼀个列表较为合适。
3)    ⽤属性来代替global变量,毕竟global变量总给⼈⼀种很不⼯整的感觉。
4)    设计每⼀个页⾯的时候只写布局和指定每个控件信号对应的槽。
5)    尽量避免定时器的使⽤。
6)    将⿏标和键盘绑定在和菜单相关的对象上,⽽⾮窗体对象本⾝。
设计框架
1)    设计⼀个⽗类,其中包含存储控件和全局变量的容器。
2)    设计⼀个函数统⼀管理action。
3)    设计⼀个函数统⼀管理menu Bar。
4)    设计⼀个函数,使得该函数针对同类型和槽函数均相同的组件可以批量创建。
5)    设计⼀个函数,使得该函数可以⾃动读取存储的数据,并且根据读取的内容调整相关的控件的各种参数。
5)    针对每⼀个页⾯,设计⼀个函数来进⾏布局和指定每个控件信号对应的槽。
6)    针对每⼀个页⾯,设计⼀个函数来写⾃定义槽。
6)    设计⼀个代数模块来统⼀管理⾃定义的代数计算相关的类。
7)    设计⼀个画布模块来统⼀管理后台的即时动画计算和静态图形的绘制。
代码(框架分部)
容器:
1#!/usr/bin/python
2
3
4class MainData:
元旦高速2023免费吗5"""
6    frame of page data about PyQt5
7"""
8
9def__init__(self):
10        self.action = dict()
11        self.canvas = dict()
12        l = {"QLabel": [], "QTabWidget": [], "QPushButton": [], "QTextEdit": [],
13"QRadioButton": [], "QComboBox": [], "QSpinBox": [], "QTableWidget": [], "QLCDNumber": []}
14        lData = dict()
15
16def controlClear(self):
17"""
18        remove all the controls except menuBar before open a new page
19"""
20        l = {"QLabel": [], "QTabWidget": [], "QPushButton": [], "QTextEdit": [], 21"QRadioButton": [], "QComboBox": [], "QSpinBox": [], "QTableWidget": [], "QLCDNumber": []} 22
23def addFrame(self, imageName):
24"""
25        add a empty dictionary to record page data
26"""
27        lData[imageName] = dict()
28        lData[imageName]["QRadioButton"] = {"isChecked": []}
29        lData[imageName]["QComboBox"] = {"itemText": [], "currentIndex": []}
30        lData[imageName]["QSpinBox"] = {"value": []}
31        lData[imageName]["QTableWidget"] = {"data": []}
32        lData[imageName]["QLCDNumber"] = {"value": []}
33        lData[imageName]["save"] = []
34
35def controlDataClear(self, imageName):
36"""
37        remove data  before refresh current page
38"""
39        lData[imageName]["QRadioButton"]["isChecked"] = []
40        lData[imageName]["QComboBox"]["itemText"] = []
41        lData[imageName]["QComboBox"]["currentIndex"] = []
42        lData[imageName]["QSpinBox"]["value"] = []
43        lData[imageName]["QTableWidget"]["data"] = []
44        lData[imageName]["QLCDNumber"]["value"] = []
45        lData[imageName]["save"] = []
MainData
窗体:
1#!/usr/bin/python
2# coding=utf-8
3
4from__future__import division
5from MainData import MainData
6from CanvasManager import *
7from AlgorithmManager import *
8from PyQt5.QtCore import Qt
9from PyQt5.QtGui import (QIcon, QFont)
10from PyQt5.QtWidgets import (qApp,
11                              QAction,
12                              QComboBox,
13                              QDesktopWidget,
14                              QFileDialog,
15                              QGridLayout,
16                              QInputDialog,
17                              QRadioButton,
18                              QLabel,
19                              QLCDNumber,
20                              QMainWindow,
21                              QMessageBox,
22                              QPushButton,
23                              QSpinBox,
24                              QTableWidget,
25                              QTableWidgetItem,
26                              QTabWidget,
27                              QTextEdit,
28                              QToolTip,
29                              QWidget)
30
31
32# noinspection PyNonAsciiChar
33class App(QMainWindow, MainData):
34"""
35    @
36"""
37
38# noinspection PyArgumentList,PyMissingConstructor
39def__init__(self):
40# noinspection PyCompatibility
41        QMainWindow.__init__(self)
42
43# noinspection PyCallByClass,PyTypeChecker
44        QToolTip.setFont(QFont('SansSerif', 10))
45        self.setGeometry(100, 100, 900, 550)
46        qr = self.frameGeometry()
47        cp = QDesktopWidget().availableGeometry().center()
48        qr.moveCenter(cp)
49        pLeft())
50        self.setWindowTitle('MathDemo')
51        self.setWindowIcon(QIcon('python.png'))
52        self.setWindowFlags(Qt.WindowStaysOnTopHint)
如何格式化53
54        self.actionLoad()
55
56        uBarLoad()
57
58>>>>>>>>>
59# set current image that you are operating. #
60>>>>>>>>>
61        self.currentImage = ""
62        self.rainImage()
63
64        self.statusBar().showMessage('Ready')
65
66        self.show()
67
68def actionLoad(self):
69"""
70        set MainData.action
71"""
72
73        self.action["showOpenDialog"] = QAction('Open File', self)
74        self.action["showOpenDialog"].setIcon(QIcon('open.png'))
75        self.action["showOpenDialog"].setShortcut('Ctrl+O')
76        self.action["showOpenDialog"].setStatusTip('Open File')
77        self.action["showOpenDialog"].t(self.showOpenDialog)
78
79        self.action["qApp.quit"] = QAction('Exit application', self)
80        self.action["qApp.quit"].setIcon(QIcon('exit.jpg'))
81        self.action["qApp.quit"].setShortcut('Ctrl+Q')
82        self.action["qApp.quit"].setStatusTip('Exit application')
83        self.action["qApp.quit"].t(qApp.quit)
84
85        self.action["orthogonalTableImage"] = QAction('Orthogonal Table', self)
86        self.action["orthogonalTableImage"].setIcon(QIcon('numpy_logo.jpg'))
87        self.action["orthogonalTableImage"].setShortcut('Ctrl+T')
88        self.action["orthogonalTableImage"].setStatusTip('Orthogonal Table')
89        self.action["orthogonalTableImage"].hogonalTableImage)
遗忘保卫者在哪换
90
91        self.action["convexHullImage"] = QAction('Convex Hull', self)
92        self.action["convexHullImage"].setIcon(QIcon('numpy_logo.jpg'))
93        self.action["convexHullImage"].setShortcut('Ctrl+C')
94        self.action["convexHullImage"].setStatusTip('Convex Hull')
95        self.action["convexHullImage"].vexHullImage)
96
97        self.action["gravitationalSystemImage"] = QAction('Gravitational System', self)
98        self.action["gravitationalSystemImage"].setIcon(QIcon('scipy_logo.jpg'))
99        self.action["gravitationalSystemImage"].setShortcut('Ctrl+G')
100        self.action["gravitationalSystemImage"].setStatusTip('Gravitational System')
101        self.action["gravitationalSystemImage"].avitationalSystemImage) 102
103        self.action["analyticFunctionImage"] = QAction('Analytic Function', self)
104        self.action["analyticFunctionImage"].setIcon(QIcon('numpy_logo.jpg'))
105        self.action["analyticFunctionImage"].setShortcut('Ctrl+A')
106        self.action["analyticFunctionImage"].setStatusTip('Analytic Function')
107        self.action["analyticFunctionImage"].t(self.analyticFunctionImage)
108
109        self.action["sourceCodeImage"] = QAction('Source Code', self)
110        self.action["sourceCodeImage"].setShortcut('F2')
111        self.action["sourceCodeImage"].setStatusTip('Source Code')
112        self.action["sourceCodeImage"].t(self.sourceCodeImage)
113
114def menuBarLoad(self):
115"""
116        uBar
117"""
118        self.statusBar()
119        menubar = uBar()
120
121        fileMenu = menubar.addMenu('&File')
122        fileMenu.addAction(self.action["showOpenDialog"])
123        fileMenu.addAction(self.action["qApp.quit"])
124
125        statisticsMenu = menubar.addMenu('&Statistics')
126        statisticsMenu.addAction(self.action["orthogonalTableImage"])
127
128        statisticsMenu = menubar.addMenu('&Geometry')
129        statisticsMenu.addAction(self.action["convexHullImage"])
130
131        statisticsMenu = menubar.addMenu('&Ode')
132        statisticsMenu.addAction(self.action["gravitationalSystemImage"])
133
134        statisticsMenu = menubar.addMenu('&Complex')
135        statisticsMenu.addAction(self.action["analyticFunctionImage"])
136
137        statisticsMenu = menubar.addMenu('&Help')
138        statisticsMenu.addAction(self.action["sourceCodeImage"])
139
140def controlLayout(self, layout=None, name=None, var=None, position=None, signal=None):
141"""
142        control layout
143        :param layout: GridLayout = QGridLayout()
144        :param name: name of control, name is a string
145        :param var: var is a dict
146        :param position: position is a list with 4 numeric
147        :param signal: signal function
148"""
149if name == "QLabel":
150# var = {"text": [string]}
151for j in range(0, len(position)):
152                l[name].append(QLabel(var["text"][j]))
153                l[name][-1].setAlignment(Qt.AlignCenter)
154# noinspection PyArgumentList
155                layout.l[name][-1], position[j][0], position[j][1], position[j][2], position[j][3]) 156
157if name == "QTabWidget":
158# var = {"text": [[string]], "widget": [[PyQt5.QtWidgets.QWidget]]}
159for j in range(0, len(position)):
160                l[name].append(QTabWidget())
161for k in range(0, len(var["text"][j])):
162                    l[name][-1].addTab(var["widget"][j][k], (var["text"][j][k]))
163# noinspection PyArgumentList
164                layout.l[name][-1], position[j][0], position[j][1], position[j][2], position[j][3]) 165
166if name == "QPushButton":
167# var = {"text": [string]}
168for j in range(0, len(position)):
169                l[name].append(QPushButton(var["text"][j]))
170# noinspection PyArgumentList
171                layout.l[name][-1], position[j][0], position[j][1], position[j][2], position[j][3]) 172if signal is not None:
173                    l[name][-1].t(signal)
174
175if name == "QTextEdit":
176# var = {"text": [[string]]}
177for j in range(0, len(position)):
178                l[name].append(QTextEdit())
端敬皇后179if len(var["text"]) != 0:
180if len(var["text"][j]) != 0:
181for line in var["text"][j]:
182                            l[name][-1].append(line)
183# noinspection PyArgumentList
184                layout.l[name][-1], position[j][0], position[j][1], position[j][2], position[j][3]) 185
186if name == "QRadioButton":
187# var = {"text": [string], "isChecked": [bool]}
188for j in range(0, len(position)):
189                l[name].append(QRadioButton(var["text"][j]))
190                l[name][-1].setChecked(var["isChecked"][j])
191# noinspection PyArgumentList
192                layout.l[name][-1], position[j][0], position[j][1], position[j][2], position[j][3]) 193if signal is not None:
194                    l[name][-1].t(signal)
195
196if name == "QComboBox":
197# var = {"itemText": [[string]], "currentIndex": [int]}
198for j in range(0, len(position)):
199                l[name].append(QComboBox())
200                l[name][-1].addItems(var["itemText"][j])
201if len(var["currentIndex"]) != 0:
202                    l[name][-1].setCurrentIndex(var["currentIndex"][j])
203# noinspection PyArgumentList
204                layout.l[name][-1], position[j][0], position[j][1], position[j][2], position[j][3]) 205if signal is not None:
206                    l[name][-1].t(signal)
207
208if name == "QSpinBox":
209# var = {"range": [[int, int]], "singleStep": [int], "prefix": [string], "suffix": [string], "value": [int]}
210for j in range(0, len(position)):
211                l[name].append(QSpinBox())
212                l[name][-1].setRange(var["range"][j][0], var["range"][j][1])
213                l[name][-1].setSingleStep(var["singleStep"][j])
214if len(var["prefix"]) != 0:
215if len(var["prefix"][j]) != 0:
216                        l[name][-1].setPrefix(var["prefix"][j])
217if len(var["suffix"]) != 0:
218if len(var["suffix"][j]) != 0:
219                        l[name][-1].setSuffix(var["suffix"][j])
220                l[name][-1].setValue(var["value"][j])
221# noinspection PyArgumentList
222                layout.l[name][-1], position[j][0], position[j][1], position[j][2], position[j][3]) 223if signal is not None:
224                    l[name][-1].t(signal)
225
226if name == "QTableWidget":
227# var = {"headerLabels": [[string]], "data": [numpy.array]}
228for i in range(0, len(position)):
229                l[name].append(QTableWidget(1, 1))
230if len(var["headerLabels"]) != 0:
231if len(var["headerLabels"][i]) != 0:
232                        l[name][-1].setColumnCount(len(var["headerLabels"][i]))
233                        l[name][-1].setHorizontalHeaderLabels(var["headerLabels"][i])
234if len(var["data"]) != 0:
235if len(var["data"][i]) != 0:
236                        row, column = var["data"][i].shape
237                        l[name][-1].setRowCount(row)
238                        l[name][-1].setColumnCount(column)
239for j in range(0, row):
240for k in range(0, column):
241                                newItem = QTableWidgetItem(str(var["data"][i][j][k]))怎么回qq密码
242                                l[name][-1].setItem(j, k, newItem)
243                l[name][-1].resizeColumnsToContents()
244# noinspection PyArgumentList
245                layout.l[name][-1], position[i][0], position[i][1], position[i][2], position[i][3]) 246
247if name == "QLCDNumber":
248# var = {"value": [int]}
249for j in range(0, len(position)):
250                l[name].append(QLCDNumber(self))
251if len(var["value"]) != 0:
252if len(var["value"][j]) != 0:
253                        l[name][-1].display(var["value"][j])
254else:
255                        l[name][-1].display(0)
256# noinspection PyArgumentList
257                layout.l[name][-1], position[j][0], position[j][1], position[j][2], position[j][3]) 258
259def imageRead(self, imageName=None):
260"""
261        load data into current page, or write data from current page.
262"""
263if l["QRadioButton"]) != 0:
264            length = l["QRadioButton"])
265for j in range(0, length):
266                isChecked = lData[imageName]["QRadioButton"]["isChecked"][j]
267                l["QRadioButton"][j].setChecked(isChecked)
268
269if l["QComboBox"]) != 0:
270pass
271
272if l["QComboBox"]) != 0:
273            length = l["QComboBox"])
华为企业价值观
274for j in range(0, length):
275                currentIndex = lData[imageName]["QComboBox"]["currentIndex"][j]
276                l["QComboBox"][j].setCurrentIndex(currentIndex)
277
278if l["QSpinBox"]) != 0:
279            length = l["QSpinBox"])
280for j in range(0, length):
281                value = lData[imageName]["QSpinBox"]["value"][j]
282                l["QSpinBox"][j].setValue(value)
283
284if l["QTableWidget"]) != 0:
285            length = l["QTableWidget"])
286for i in range(0, length):
287                data = lData[imageName]["QTableWidget"]["data"][i]
288                row, column = data.shape
289                l["QTableWidget"][i].setRowCount(row)
290                l["QTableWidget"][i].setColumnCount(column)
291for j in range(0, row):
292for k in range(0, column):
293                        newItem = QTableWidgetItem(str(data[j][k]))
294                        l["QTableWidget"][i].setItem(j, k, newItem)
295                l["QTableWidget"][i].resizeColumnsToContents()
296
297if l["QLCDNumber"]) != 0:
298            length = l["QLCDNumber"])
299for j in range(0, length):
300                value = lData[imageName]["QLCDNumber"]["value"][j]
301                l["QLCDNumber"][j].display(value)
302
303def rainImage(self):

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。

发表评论