文章目录
- 前言
- UI设计
- 代码
前言
为什么我要设计这个程序呢?因为我要用,懒得在网上下载了,于是干脆写了一个。
UI设计
UI是我凹出来的,你们要使用,直接新建一个UI.ui文件,然后把下面的东西输进去就可以了。
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0"><class>MainWindow</class><widget class="QMainWindow" name="MainWindow"><property name="geometry"><rect><x>0</x><y>0</y><width>283</width><height>365</height></rect></property><property name="windowTitle"><string>MainWindow</string></property><widget class="QWidget" name="centralwidget"><widget class="QLabel" name="label"><property name="geometry"><rect><x>20</x><y>10</y><width>81</width><height>21</height></rect></property><property name="font"><font><pointsize>12</pointsize></font></property><property name="text"><string>起始数字:</string></property></widget><widget class="QSpinBox" name="SPstart"><property name="geometry"><rect><x>130</x><y>10</y><width>131</width><height>22</height></rect></property><property name="minimum"><number>-999999999</number></property><property name="maximum"><number>999999999</number></property></widget><widget class="QLabel" name="label_2"><property name="geometry"><rect><x>20</x><y>50</y><width>81</width><height>21</height></rect></property><property name="font"><font><pointsize>12</pointsize></font></property><property name="text"><string>结束数字:</string></property></widget><widget class="QSpinBox" name="SPend"><property name="geometry"><rect><x>130</x><y>50</y><width>131</width><height>22</height></rect></property><property name="minimum"><number>-999999999</number></property><property name="maximum"><number>999999999</number></property></widget><widget class="QPushButton" name="Bstart"><property name="geometry"><rect><x>50</x><y>120</y><width>81</width><height>31</height></rect></property><property name="text"><string>生成</string></property></widget><widget class="QTextBrowser" name="textN"><property name="geometry"><rect><x>30</x><y>170</y><width>221</width><height>101</height></rect></property></widget><widget class="QCheckBox" name="checkBox"><property name="geometry"><rect><x>170</x><y>130</y><width>71</width><height>16</height></rect></property><property name="text"><string>去重</string></property></widget><widget class="QPushButton" name="Bcopy"><property name="geometry"><rect><x>100</x><y>280</y><width>81</width><height>31</height></rect></property><property name="text"><string>复制</string></property></widget><widget class="QSpinBox" name="SPquantity"><property name="geometry"><rect><x>130</x><y>90</y><width>131</width><height>22</height></rect></property><property name="minimum"><number>-999999999</number></property><property name="maximum"><number>999999999</number></property></widget><widget class="QLabel" name="label_3"><property name="geometry"><rect><x>20</x><y>90</y><width>81</width><height>21</height></rect></property><property name="font"><font><pointsize>12</pointsize></font></property><property name="text"><string>生成数量:</string></property></widget></widget><widget class="QMenuBar" name="menubar"><property name="geometry"><rect><x>0</x><y>0</y><width>283</width><height>23</height></rect></property></widget><widget class="QStatusBar" name="statusbar"/><action name="action"><property name="text"><string>1</string></property></action></widget><resources/><connections/>
</ui>
然后这个UI的效果应该是这样的:
代码
这玩意儿搞完了以后,就这样新建文件夹及文件:
新建完以后,就写基本框架了。
首先,先在main.py中写上框架:
import sys
from PyQt5 import QtWidgets, uic
import random #这个东西有大用formClass = uic.loadUiType(【UI.ui的路径】)[0]class RandomNumberGenerator(QtWidgets.QMainWindow, formClass):def __init__(self):super().__init__()self.setupUi(self)app = QtWidgets.QApplication(sys.argv)
window = RandomNumberGenerator()
window.show()
app.exec_()
我这里控件等窗口里的东西的名字都不是很标准,你们看看就好,别学我。
首先,先设置数量这个控件的下限为1,放在类中的__init__里:
class RandomNumberGenerator(QtWidgets.QMainWindow, formClass):def __init__(self):super().__init__()self.setupUi(self)self.SPquantity.setMinimum(1)
然后,绑定每个按钮要处理的事件,并定义好随机数列表,同样放在__init__里:
class RandomNumberGenerator(QtWidgets.QMainWindow, formClass):def __init__(self):super().__init__()self.setupUi(self)self.randomNumber = []self.SPquantity.setMinimum(1)self.Bstart.clicked.connect(self.start)self.Bcopy.clicked.connect(self.copy)
然后就是处理开始生成的事件:
def start(self):if not self.checkBox.isChecked(): #如果去重多选框没有勾选(我懒得重命名这个多选框了)self.randomNumber = [] #清空for i in range(self.SPquantity.value()):self.randomNumber.append(str(random.randint(int(self.SPstart.value()), int(self.SPend.value())))) #分开讲,就是先随机,然后加入随机数列表self.textN.clear() #清空结果self.textN.setText(",".join(self.randomNumber)) #显示随机数else: #反之,如果勾选了self.randomNumber = [] #一样先清空tempL = [i for i in range(int(self.SPstart.value()), int(self.SPend.value())+1)] #把所有范围内的数字列出来for i in range(self.SPquantity.value()): #重复执行 数量 次num = random.choice(tempL) #随机选择self.randomNumber.append(num) #加入(可以把上一行合并在这一行)tempL.remove(num) #删除,也就是防止再次选择到这个数字self.textN.clear() #清空结果self.textN.setText(",".join(self.randomNumber)) #显示结果
然后,就是处理复制按钮的事件了,很简单,不过别忘了在开头加上导入库的代码:
import pyperclip #这个东西要放在开头
def copy(self):pyperclip.copy(self.textN.toPlainText())QtWidgets.QMessageBox.information(self, "提示", "随机数已复制到剪贴板") #删掉也可以
接着,运行一下代码,然后你就会发现
有Bug!
于是,我们就有两个选择:
- 特判数据,如果出现结果不正常的情况就报错。
- 直接修改SpinBox的上限和下限,从源头阻止Bug。
显然,我肯定会选第二个,然后,就变得复杂起来了
首先,修改我们的__init__方法:
def __init__(self):super().__init__()self.randomNumber = []self.setupUi(self)self.SPquantity.setMinimum(1)self.Bstart.clicked.connect(self.start)self.Bcopy.clicked.connect(self.copy)# 增加这四行:self.SPstart.valueChanged.connect(self.updateSPend)self.checkBox.stateChanged.connect(self.updateSPquantity)self.SPstart.valueChanged.connect(self.updateSPquantity)self.SPend.valueChanged.connect(self.updateSPquantity)
然后就码代码:
def updateSPend(self):self.SPend.setMinimum(self.SPstart.value())def updateSPquantity(self):if self.checkBox.isChecked():self.SPquantity.setMaximum(int(self.SPend.value()) - int(self.SPstart.value()) + 1)else:self.SPquantity.setMaximum(999999999)
至于为什么我不注释……因为当时我忘了,现在又想不起来为什么要这么写了,将就着看吧。
好了,终于来到激动人心的时刻:合并代码:
import sys
from PyQt5 import QtWidgets, uic
import random
import pyperclipformClass = uic.loadUiType(【UI.ui的路径】)[0]class RandomNumberGenerator(QtWidgets.QMainWindow, formClass):def __init__(self):super().__init__()self.randomNumber = []self.setupUi(self)self.SPquantity.setMinimum(1)self.Bstart.clicked.connect(self.start)self.Bcopy.clicked.connect(self.copy)self.SPstart.valueChanged.connect(self.updateSPend)self.checkBox.stateChanged.connect(self.updateSPquantity)self.SPstart.valueChanged.connect(self.updateSPquantity)self.SPend.valueChanged.connect(self.updateSPquantity)def updateSPend(self):self.SPend.setMinimum(self.SPstart.value())def updateSPquantity(self):if self.checkBox.isChecked():self.SPquantity.setMaximum(int(self.SPend.value()) - int(self.SPstart.value()) + 1)else:self.SPquantity.setMaximum(999999999)def start(self):if not self.checkBox.isChecked(): #如果去重多选框没有勾选(我懒得重命名这个多选框了)self.randomNumber = [] #清空for i in range(self.SPquantity.value()):self.randomNumber.append(str(random.randint(int(self.SPstart.value()), int(self.SPend.value())))) #分开讲,就是先随机,然后加入随机数列表self.textN.clear() #清空结果self.textN.setText(",".join(self.randomNumber)) #显示随机数else: #反之,如果勾选了self.randomNumber = [] #一样先清空tempL = [i for i in range(int(self.SPstart.value()), int(self.SPend.value())+1)] #把所有范围内的数字列出来for i in range(self.SPquantity.value()): #重复执行 数量 次num = random.choice(tempL) #随机选择self.randomNumber.append(num) #加入(可以把上一行合并在这一行)tempL.remove(num) #删除,也就是防止再次选择到这个数字self.textN.clear() #清空结果self.textN.setText(",".join(self.randomNumber)) #显示结果def copy(self):pyperclip.copy(self.textN.toPlainText())QtWidgets.QMessageBox.information(self, "提示", "随机数已复制到剪贴板")app = QtWidgets.QApplication(sys.argv)
window = RandomNumberGenerator()
window.show()
app.exec_()
然后,完结撒花(了吗?)
肯定没有。因为我后来发现如果要移动这个小程序,一直修改UI.ui的路径太费时间了,于是,我自己写了点自动搜索路径的代码,于是就变得更方便了:
最后,这是所有的代码了(不会再改了):
import sys
from PyQt5 import QtWidgets, uic
import random
import pyperclip
import pathlibpath = pathlib.Path(__file__)
while path.name != "randomNumberGenerator":path = path.parent
for i in path.rglob("*.ui"):if i.name == 'UI.ui':path = ibreakformClass = uic.loadUiType(path)[0]class RandomNumberGenerator(QtWidgets.QMainWindow, formClass):def __init__(self):super().__init__()self.randomNumber = []self.setupUi(self)self.SPquantity.setMinimum(1)self.Bstart.clicked.connect(self.start)self.Bcopy.clicked.connect(self.copy)self.SPstart.valueChanged.connect(self.updateSPend)self.checkBox.stateChanged.connect(self.updateSPquantity)self.SPstart.valueChanged.connect(self.updateSPquantity)self.SPend.valueChanged.connect(self.updateSPquantity)def updateSPend(self):self.SPend.setMinimum(self.SPstart.value())def updateSPquantity(self):if self.checkBox.isChecked():self.SPquantity.setMaximum(int(self.SPend.value()) - int(self.SPstart.value()) + 1)else:self.SPquantity.setMaximum(999999999)def start(self):if not self.checkBox.isChecked(): #如果去重多选框没有勾选(我懒得重命名这个多选框了)self.randomNumber = [] #清空for i in range(self.SPquantity.value()):self.randomNumber.append(str(random.randint(int(self.SPstart.value()), int(self.SPend.value())))) #分开讲,就是先随机,然后加入随机数列表self.textN.clear() #清空结果self.textN.setText(",".join(self.randomNumber)) #显示随机数else: #反之,如果勾选了self.randomNumber = [] #一样先清空tempL = [i for i in range(int(self.SPstart.value()), int(self.SPend.value())+1)] #把所有范围内的数字列出来for i in range(self.SPquantity.value()): #重复执行 数量 次num = random.choice(tempL) #随机选择self.randomNumber.append(num) #加入(可以把上一行合并在这一行)tempL.remove(num) #删除,也就是防止再次选择到这个数字self.textN.clear() #清空结果self.textN.setText(",".join(self.randomNumber)) #显示结果def copy(self):pyperclip.copy(self.textN.toPlainText())QtWidgets.QMessageBox.information(self, "提示", "随机数已复制到剪贴板")app = QtWidgets.QApplication(sys.argv)
window = RandomNumberGenerator()
window.show()
app.exec_()
这下,是真的完结撒花了。
如果有改代码的建议,记得评论。
# _oo0oo_
# o8888888o
# 88" . "88
# (| -_- |)
# 0\ = /0
# ___/`---'\___
# .' \\| |// '.
# / \\||| : |||// \
# / _||||| -:- |||||- \
# | | \\\ - /// | |
# | \_| ''\---/'' |_/ |
# \ .-\__ '-' ___/-. /
# ___'. .' /--.--\ `. .'___
# ."" '< `.___\_<|>_/___.' >' "".
# | | : `- \`.;`\ _ /`;.`/ - ` : | |
# \ \ `_. \_ __\ /__ _/ .-` / /
# =====`-.____`.___ \_____/___.-`___.-'=====
# `=---='# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~# 佛祖保佑 永不宕机 永无BUG
后记:我的文章发布时再看不知道为什么只剩一半了,还好自动保存救了我一命QAQ。