前言
为什么我要设计这个程序呢?因为我要用,懒得在网上下载了,于是干脆写了一个。
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 pyperclip
formClass = 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 pathlib
path = pathlib.Path(__file__)
while path.name != "randomNumberGenerator":
path = path.parent
for i in path.rglob("*.ui"):
if i.name == 'UI.ui':
path = i
break
formClass = 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。