我的开发日志:随机数小程序

文章目录

前言

为什么我要设计这个程序呢?因为我要用,懒得在网上下载了,于是干脆写了一个。

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的效果应该是这样的:
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!

于是,我们就有两个选择:

  1. 特判数据,如果出现结果不正常的情况就报错。
  2. 直接修改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。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值