PyQt5中的例外工作没有按预期工作

时间:2018-01-12 12:33:38

标签: python excel exception pyqt pyqt5

我正在PyQt5中创建一个表单对话框。该程序的目标是根据零件类型根据特定格式生成数字,并将这些数字存储在Excel工作表中。 excel表名为' Master Part Sheet.xlsx'并存储在与脚本相同的目录中。可以在workbookLayer类中更改Excel工作表的名称。生成的数量由所需部件号字段

中的条目确定

在下拉菜单中选择的客户也会在生成部件号时发挥作用(仅当它是机器部件时)。将0-99之间的数字存储在字典中,针对在生成相应部件号时访问的每个客户名称。

当用户在其中输入值时,必须检查输入字段。每次输入的值不正确(不在某个范围内/不在指定格式中)时,都会调用异常。单击表单对话框中的生成Qpush按钮时,将检查这些值。

NTID字段的格式必须为UUUNUUU,其中U代表大写字符串,N代表数字。使用正则表达式检查它,否则必须抛出异常。

计算机编号行号字段必须在 0-99 范围内,否则必须抛出异常提示用户检查他/她在消息标签中的条目。

用户输入数据并进行这些检查后,必须生成部件号并将其写入Excel工作表。

如果零件类型是标准零件,则零件编号将写入工作簿的标准零件表。此工作表中可存在的最大部件数为10000.部件号必须是唯一的。

如果工作表是机器零件,则会在工作簿中创建新工作表,其中会写入零件编号。工作表根据客户名称(机器编号和行号)创建。一张纸最多可以有1000张,所产生的数字不应该在纸张中重复,即它们是唯一的。

以下是代码

'''import all necessary libraries required for the project'''

import os
import numpy as np
import openpyxl
from openpyxl.workbook import Workbook
from openpyxl import load_workbook
import random
import time
import pickle
import re

class workbookLayer:

'''The constructor for the workbook object'''

    def __init__(self, source_file='Master Part Sheet.xlsx'): # Change source_file to get different sheet as source

        self.source_file = source_file
        self.part_type = None
        self.line_number = None
        self.machine_number = None
        self.customer_name = None
        self.ntid = None
        self.get_sheet_name()
    '''Get the path of the Excel workbook and load the workbook onto the object'''
    def get_sheet_name(self):

        self.file_path = os.path.realpath(self.source_file)
        self.wb = load_workbook(self.file_path)
        self.wb.get_sheet_names()
        return self.file_path, self.wb

from PyQt5.QtWidgets import (QApplication, QComboBox, QDialog,
        QDialogButtonBox, QFormLayout, QGridLayout, QGroupBox, QHBoxLayout,
        QLabel, QLineEdit, QMenu, QMenuBar, QPushButton, QSpinBox, QTextEdit,
        QVBoxLayout, QMessageBox)

import sys
'''The Pop up Box for addition of a new customer'''
class DialogCustomerAdd(QDialog):
    NumGridRows = 3
    NumButtons = 4

    def __init__(self):
        super(DialogCustomerAdd, self).__init__()
        self.createFormGroupBox()
        self.ok_button=QPushButton("OK")

        mainLayout = QVBoxLayout()
        mainLayout.addWidget(self.formGroupBox)
        mainLayout.addWidget(self.ok_button)
        self.ok_button.clicked.connect(self.ok_button_action)
        self.setLayout(mainLayout)
        self.setWindowTitle("Add New Customer")

    def ok_button_action(self):

        global CUSTOMER_NAME
        global CUSTOMER_ID
        CUSTOMER_NAME = self.customer_name_text.text()
        CUSTOMER_ID = self.customer_id_text.text()
        self.close()

    def createFormGroupBox(self):

        self.formGroupBox = QGroupBox("Customer Details")
        layout = QFormLayout()
        self.customer_name_label = QLabel("Name of the Customer")
        self.customer_name_text = QLineEdit()

        self.customer_id_label = QLabel("Enter Customer ID")
        self.customer_id_text = QLineEdit()

        layout.addRow(self.customer_name_label, self.customer_name_text)
        layout.addRow(self.customer_id_label, self.customer_id_text)

        self.formGroupBox.setLayout(layout)

'''The Pop up Box for deletion of an existing customer'''
class DialogCustomerDelete(QDialog):
    NumGridRows = 3
    NumButtons = 4

   def __init__(self):
        super(DialogCustomerDelete, self).__init__()
        self.createFormGroupBox()
        self.ok_button=QPushButton("OK")

        mainLayout = QVBoxLayout()
        mainLayout.addWidget(self.formGroupBox)
        mainLayout.addWidget(self.ok_button)
        self.ok_button.clicked.connect(self.ok_button_action)
        self.setLayout(mainLayout)
        self.setWindowTitle("Delete Existing Customer")



    def ok_button_action(self):
        global POP_CUSTOMER
        POP_CUSTOMER = self.customer_delete_combobox.currentText()
        self.customer_delete_combobox.clear()
        self.close()


    def createFormGroupBox(self):

        self.formGroupBox = QGroupBox("Customer Details")
        layout = QFormLayout()
        self.customer_name_label = QLabel(" Select the Customer to be deleted")
        self.customer_delete_combobox = QComboBox()
        self.customer_delete_combobox.addItems(CUSTOMER_LIST)

        layout.addRow(self.customer_name_label)
        layout.addRow(self.customer_delete_combobox)

        self.formGroupBox.setLayout(layout)

class DialogMain(QDialog):
    NumGridRows = 3
    NumButtons = 4

    wbl = workbookLayer() 

    def __init__(self):
        super(DialogMain, self).__init__()
        self.createFormGroupBox()

        generate_button=QPushButton("Generate")
        generate_button.clicked.connect(self.generateNumbers)
        self.user_message_label = QLabel(" ")

        buttonBox = QDialogButtonBox(QDialogButtonBox.Cancel)

        mainLayout = QVBoxLayout()
        mainLayout.addWidget(self.formGroupBox)
        mainLayout.addWidget(self.user_message_label)
        mainLayout.addWidget(generate_button)
        mainLayout.addWidget(self.add_new_customer_button)
        mainLayout.addWidget(self.delete_customer_button)
        buttonBox.clicked.connect(self.closeIt)
        mainLayout.addWidget(buttonBox)
        self.setLayout(mainLayout)


        self.open_or_create_pickle_file()
        customer_name = [customer for customer,customer_id in self.customer_dict.items()]
        self.customer_name_combobox.addItems(customer_name)
        self.add_new_customer_button.clicked.connect(self.add_customer_window)
        self.delete_customer_button.clicked.connect(self.delete_customer_window)
        self.setWindowTitle("Part Number Generator ")
        global CUSTOMER_LIST
        CUSTOMER_LIST = customer_name

    def open_or_create_pickle_file(self): 
        self.customer_dict = dict()
        try:
            assert open("customer_diction.pickle","rb")
            pickle_in = open("customer_diction.pickle","rb")
            self.customer_dict = pickle.load(pickle_in)
            pickle_in.close() 

        except FileNotFoundError:
            pickle_out = open("customer_dict.pickle","wb")

    def add_new_customer_to_pickle(self):
        global CUSTOMER_NAME
        global CUSTOMER_ID
        global CUSTOMER_LIST
        self.customer_name_combobox.addItem(CUSTOMER_NAME) 
        self.customer_dict[CUSTOMER_NAME] = CUSTOMER_ID
        customer_name = [customer for customer,customer_id in self.customer_dict.items()]
        CUSTOMER_LIST = customer_name
        pickle_out = open("customer_diction.pickle","wb")
        pickle.dump(self.customer_dict, pickle_out)
        pickle_out.close()

    def delete_customer_from_pickle(self):
        global POP_CUSTOMER
        del self.customer_dict[POP_CUSTOMER]
        customer_name = [customer for customer,customer_id in self.customer_dict.items()]
        global CUSTOMER_LIST
        CUSTOMER_LIST = customer_name
        self.customer_name_combobox.clear() 
        self.customer_name_combobox.addItems(customer_name)
        pickle_out = open("customer_diction.pickle","wb")
        pickle.dump(self.customer_dict, pickle_out)
        pickle_out.close()


    def add_customer_window(self):
        widget = DialogCustomerAdd()
        widget.exec_()

        self.add_new_customer_to_pickle()

    def delete_customer_window(self):
        widget = DialogCustomerDelete()
        widget.exec_()
        self.delete_customer_from_pickle()
        global POP_CUSTOMER
        self.user_message_label.setText('The customer ' + POP_CUSTOMER + ' has been deleted' )


    def closeIt(self): 
        self.close()

    def generateNumbers(self):

        self.wbl.line_number = self.line_number_text.text()
        self.wbl.machine_number = self.machine_number_text.text()
        self.wbl.customer_name =self.customer_name_combobox.currentText()
        self.wbl.part_type = self.part_type_combobox.currentText()
        self.wbl.ntid = self.ntid_text.text()  


        try:
            self.check_ntid()
        except AssertionError:
            self.user_message_label.setText('Please Enter User Details Correctly')

        try:
            if int(self.wbl.machine_number) > 99:
                raise ValueError
        except ValueError:
            self.user_message_label.setText('Please Enter machine number within 100')

        try:
            if int(self.wbl.line_number) > 99:
                raise ValueError
        except ValueError:
            self.user_message_label.setText('Please Enter Line number within 100')


        self.create_sheet_and_check_values()

        try:
            self.part_number_generator()
        except PermissionError:
            self.user_message_label.setText('Please Close the excel sheet before using this application')



    def createFormGroupBox(self):
        self.formGroupBox = QGroupBox("Part Details")
        layout = QFormLayout()

        self.part_type_label = QLabel("Part Type:")
        self.part_type_combobox = QComboBox()
        self.part_type_combobox.addItems(['Standard Part', 'Machine Part'])

        self.customer_name_label = QLabel("Customer:")
        self.customer_name_combobox = QComboBox()
        self.add_new_customer_button = QPushButton("Add New Customer")
        self.delete_customer_button = QPushButton("Delete Existing Customer")

        self.ntid_label = QLabel("NTID of the User:")
        self.ntid_text = QLineEdit()

        self.machine_number_label = QLabel("Machine Number of the Part:")
        self.machine_number_text = QLineEdit()

        self.line_number_label = QLabel("Line Number of the Part:")
        self.line_number_text = QLineEdit()

        self.part_numbers_label = QLabel("Number of Part Numbers Required:")
        self.part_numbers_spinbox = QSpinBox()
        self.part_numbers_spinbox.setRange(1, 999)

        layout.addRow(self.part_type_label, self.part_type_combobox)
        layout.addRow(self.customer_name_label, self.customer_name_combobox)

        layout.addRow(self.ntid_label, self.ntid_text)
        layout.addRow(self.machine_number_label, self.machine_number_text)
        layout.addRow(self.line_number_label, self.line_number_text)
        layout.addRow(self.part_numbers_label, self.part_numbers_spinbox)
        self.formGroupBox.setLayout(layout)




    def  check_ntid(self):

            pattern = re.compile("^[A-Z][A-Z][A-Z][0-9][A-Z][A-Z][A-Z]")
            assert pattern.match(self.wbl.ntid)


    def create_sheet_and_check_values(self):

        self.check_ntid()

        if self.wbl.part_type == 'Machine Part':
            self.prefix = int('3' +   self.customer_dict[self.wbl.customer_name] + self.wbl.line_number + self.wbl.machine_number)
            self.check_and_create_customer_sheet()
        else:
            self.prefix = 500000
            self.add_standard_parts_sheet()

        self.dest_filename = self.wbl.file_path


        self.ws1 = self.wbl.wb[self.wbl.sheet_name]
        self.random_numbers = self.part_numbers_spinbox.value()

        if (self.wbl.part_type == 'Machine Part'):
            try:
                assert self.random_numbers <  (1002 -(self.ws1.max_row))
            except AssertionError:
                self.user_message_label.setText('You have exceeded the range of allowable parts in the machine, you can get only {} more part numbers'.format(1001 -(self.ws1.max_row)))                
        else:
            try:
                assert self.random_numbers <  (10002 -(self.ws1.max_row))
            except AssertionError:
               self.user_message_label.setText('You have exceeded the range of allowable parts in this list, you can get only {} more part numbers'.format(10001 -(self.ws1.max_row)))

        '''This section of the method contains the logic for the generation of random number parts 
       according to the required format and also checks for clashes with already existing part numbers'''

    def part_number_generator(self):

        if (self.wbl.part_type == 'Machine Part'):
            part_numbers_list = random.sample(range( self.prefix*1000, self.prefix*1000 + 1000), self.random_numbers)
        else:
            part_numbers_list = random.sample(range( self.prefix*10000, self.prefix*10000 + 10000), self.random_numbers)


        first_column = set([(self.ws1[x][0].value) for x in range(2,self.ws1.max_row + 1 )])

        while True:
            additional_part_numbers_list = random.sample(range( self.prefix*1000, self.prefix*1000 + 1000), self.random_numbers - len (part_numbers_list))

            part_numbers_list = part_numbers_list + additional_part_numbers_list 

            part_numbers_list = list(set(part_numbers_list) - (first_column))

            if len(part_numbers_list) == self.random_numbers:
                break

        for row in range( self.ws1.max_row + 1, self.ws1.max_row + 1 + len(part_numbers_list)):
            '''write the generated part numbers onto the excel sheet corresponding to the customer'''

            self.ws1.cell(column = 1 , row = row, value = part_numbers_list.pop())
            self.ws1.cell(column = 3 , row = row, value = self.wbl.ntid)


        self.wbl.wb.save(self.wbl.file_path)

        self.user_message_label.setText(str(self.part_numbers_spinbox.value()) + " Part Numbers have been successfully generated. Please check the sheet " + self.wbl.sheet_name)


    def check_and_create_customer_sheet(self):
        self.wbl.sheet_name = '3' + self.customer_dict[self.wbl.customer_name] + self.wbl.line_number + self.wbl.machine_number +'xxx'
        if self.customer_not_exists():
            self.wbl.wb.create_sheet(self.wbl.sheet_name)
            self.wbl.wb.save(self.wbl.file_path)


        '''Check if the customer sheet exists'''        
    def customer_not_exists(self):
        sheet_name = '<Worksheet "'+ '3' +  self.customer_dict[self.wbl.customer_name] + self.wbl.line_number + self.wbl.machine_number +'xxx' + '">'
        return True if sheet_name not in str(list(self.wbl.wb)) else False


        '''Check if standard parts sheet exists. If not make a new sheet'''
    def add_standard_parts_sheet(self):
        sheet_name = '<Worksheet "'+ 'Standard Parts'+ '">'

        if sheet_name not in str(list(self.wbl.wb)):
            self.wbl.wb.create_sheet('Standard Parts')
            self.wbl.wb.save(self.wbl.file_path)

            self.wbl.sheet_name = 'Standard Parts'


if __name__ == '__main__':
    app = QApplication(sys.argv)
    dialog = DialogMain()
sys.exit(dialog.exec_())

generateNumbers()类中的DialogMain()函数在每次生成&#39}时被调用。在QDialog布局中单击QpushButton。程序检查输入的正确性,并通过openpyxl根据excel表中所需的格式生成随机数。 self.wbl.ntidPermissionError的例外工作符合预期。 然而,对象self.wbl.machine_numberself.wb1.line_number的例外情况,即机器号输入和行号输入似乎被忽略即使用户输入错误,程序也会执行。只有NTID的例外行为符合预期,即使错误输入也无法引发其他异常。

对话框

我添加了用于使其可重现的整个代码。感谢

0 个答案:

没有答案