将一个大类分成几个子类,__ init__问题

时间:2017-01-11 17:25:19

标签: python class methods instantiation

我遇到了一个非常大的课程,我现在正试图清理并拆分成子类。但是我最大的问题是设置正确的init方法,以便在各个子类之间调用函数。 我们的想法是拥有一个Ui_MainWindow类,它正在处理gui进程。另一个处理AT命令的TextMessage类和第三个处理所有错误消息的MessageBoxes类。我如何为setupUi函数中的所有属性创建正确的init方法?这是我最大的问题。 非常感谢你提前。 大班是这里的:

    ALPHA = string.ascii_letters

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(503, 486)
        self.centralWidget = QtWidgets.QWidget(MainWindow)
        self.centralWidget.setObjectName("centralWidget")
        self.widget = QtWidgets.QWidget(self.centralWidget)
        self.widget.setGeometry(QtCore.QRect(10, 20, 477, 391))
        self.widget.setObjectName("widget")
        self.gridLayout_2 = QtWidgets.QGridLayout(self.widget)
        self.gridLayout_2.setContentsMargins(11, 11, 11, 11)
        self.gridLayout_2.setSpacing(6)
        self.gridLayout_2.setObjectName("gridLayout_2")
        self.lineEdit_2 = QtWidgets.QLineEdit(self.widget)
        self.lineEdit_2.setObjectName("lineEdit_2")
        self.lineEdit_2.setDisabled(True)
        self.gridLayout_2.addWidget(self.lineEdit_2, 0, 1, 1, 1)
        self.gridLayout = QtWidgets.QGridLayout()
        self.gridLayout.setContentsMargins(11, 11, 11, 11)
        self.gridLayout.setSpacing(6)
        self.gridLayout.setObjectName("gridLayout")
        self.radioButton = QtWidgets.QRadioButton(self.widget)
        self.radioButton.setChecked(True)
        self.radioButton.setObjectName("radioButton")
        self.gridLayout.addWidget(self.radioButton, 0, 0, 1, 1)
        self.lineEdit = QtWidgets.QLineEdit(self.widget)
        self.lineEdit.setObjectName("lineEdit")
        self.gridLayout.addWidget(self.lineEdit, 0, 1, 1, 1)
        self.radioButton_2 = QtWidgets.QRadioButton(self.widget)
        self.radioButton_2.setObjectName("radioButton_2")
        self.gridLayout.addWidget(self.radioButton_2, 1, 0, 1, 1)
        self.lineEdit2 = QtWidgets.QLineEdit(self.widget)
        self.lineEdit2.setObjectName("lineEdit2")
        self.gridLayout.addWidget(self.lineEdit2, 1, 1, 1, 1)
        self.pushButton = QtWidgets.QPushButton(self.widget)
        self.pushButton.setObjectName("pushButton")
        self.pushButton.clicked.connect(self.get_path) #connect add xls button with function get_path
        self.gridLayout.addWidget(self.pushButton, 1, 2, 1, 1)
        self.plainTextEdit = QtWidgets.QPlainTextEdit(self.widget)
        self.plainTextEdit.setObjectName("plainTextEdit")
        self.gridLayout.addWidget(self.plainTextEdit, 2, 1, 2, 1)
        self.label = QtWidgets.QLabel(self.widget)
        self.label.setObjectName("label")
        self.gridLayout.addWidget(self.label, 2, 0, 1, 1)
        self.label2 = QtWidgets.QLabel(self.centralWidget)
        self.label2.setObjectName("label2")
        self.gridLayout.addWidget(self.label2, 2, 2, 1, 1)
        self.pushButton_2 = QtWidgets.QPushButton(self.widget)
        self.pushButton_2.setObjectName("pushButton_2")
        self.gridLayout.addWidget(self.pushButton_2, 3, 2, 1, 1)
        self.pushButton_2.clicked.connect(self.send_sms) #send sms function
        self.gridLayout_2.addLayout(self.gridLayout, 1, 0, 1, 2)
        self.line = QtWidgets.QFrame(self.widget)
        self.line.setFrameShape(QtWidgets.QFrame.HLine)
        self.line.setFrameShadow(QtWidgets.QFrame.Sunken)
        self.line.setObjectName("line")
        self.gridLayout_2.addWidget(self.line, 2, 0, 1, 2)
        self.pushButton_3 = QtWidgets.QPushButton(self.widget)
        self.pushButton_3.setObjectName("pushButton_3")
        self.gridLayout_2.addWidget(self.pushButton_3, 0, 0, 1, 1)
        self.pushButton_3.clicked.connect(self.connect_phone) #connect add xls button with function get_path
        self.plainTextEdit_2 = QtWidgets.QPlainTextEdit(self.widget)
        self.plainTextEdit_2.setObjectName("plainTextEdit_2")
        self.plainTextEdit_2.setDisabled(True)
        self.gridLayout_2.addWidget(self.plainTextEdit_2, 4, 1, 2, 1)
        self.progressBar = QtWidgets.QProgressBar(self.widget)
        self.progressBar.setProperty("value", 0)
        self.progressBar.setObjectName("progressBar")
        self.gridLayout_2.addWidget(self.progressBar, 4, 0, 1, 1)
        self.checkBox = QtWidgets.QCheckBox(self.widget)
        self.checkBox.setObjectName("checkBox")
        self.gridLayout_2.addWidget(self.checkBox, 5, 0, 1, 1)
        MainWindow.setCentralWidget(self.centralWidget)
        self.menuBar = QtWidgets.QMenuBar(MainWindow)
        self.menuBar.setGeometry(QtCore.QRect(0, 0, 503, 27))
        self.menuBar.setObjectName("menuBar")
        MainWindow.setMenuBar(self.menuBar)
        self.mainToolBar = QtWidgets.QToolBar(MainWindow)
        self.mainToolBar.setObjectName("mainToolBar")
        MainWindow.addToolBar(QtCore.Qt.TopToolBarArea, self.mainToolBar)
        self.statusBar = QtWidgets.QStatusBar(MainWindow)
        self.statusBar.setObjectName("statusBar")
        MainWindow.setStatusBar(self.statusBar)

        self.retranslateUi(MainWindow)
        self.radioButton.toggled['bool'].connect(self.lineEdit.setEnabled)
        self.radioButton.toggled['bool'].connect(self.lineEdit2.setDisabled)
        self.radioButton_2.toggled['bool'].connect(self.lineEdit.setDisabled)
        self.radioButton_2.toggled['bool'].connect(self.lineEdit2.setEnabled)
        self.radioButton.toggled['bool'].connect(self.pushButton.setDisabled)
        self.radioButton_2.toggled['bool'].connect(self.pushButton.setEnabled)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)
        self.plainTextEdit.textChanged.connect(self.bam)

    def bam(self):
        _translate = QtCore.QCoreApplication.translate
    text = self.plainTextEdit.toPlainText()
        self.label2.setText(_translate("MainWindow", str(len(text))+"/160"))
    if len(text) > 160:
            root = tk.Tk()
        root.withdraw()
        self.plainTextEdit.setPlainText(text[:160])
        cursor = self.plainTextEdit.textCursor()
        cursor.setPosition(self.plainTextEdit.document().characterCount() - 1)
        self.plainTextEdit.setTextCursor(cursor)
        tkMessageBox.showwarning("No Way!", "Keep it low, 160chrs max")
        root.destroy()
        root.mainloop()
        return

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "Kotti&Co Mobilizer"))
        self.radioButton.setText(_translate("MainWindow", "Single SMS"))
        self.radioButton_2.setText(_translate("MainWindow", "SMS to Contacts"))
        self.pushButton.setText(_translate("MainWindow", "Add .xls"))
        self.label.setText(_translate("MainWindow", "Message Text"))
        self.pushButton_2.setText(_translate("MainWindow", "Send it!"))
        self.pushButton_3.setText(_translate("MainWindow", "Connect Phone"))
        self.checkBox.setText(_translate("MainWindow", "Status Report"))

    def get_path(self, MainWindow): 
        _translate = QtCore.QCoreApplication.translate
        root = tk.Tk()
    root.withdraw()
    file_path = filedialog.askopenfilename(title = "Kotti Kontaktliste",filetypes = (("excel files","*.xls"),("excel files", "*.xlsx"),("csv files","*.csv"),("all files","*.*")))
    if not file_path:
        return None
    else:
        self.lineEdit2.insert(file_path)

    def __init__(self, recipient="+491749449785", message="TextMessage.content not set."):
        self.recipient = recipient
        self.content = message

    def setRecipient(self, number):
        self.recipient = number

    def setContent(self, message):
        self.content = message

    def disconnectPhone(self):
        self.ser.close()

    def connect_phone(self):
    try:
        self.ser = serial.Serial('/dev/ttyACM0',
                    460800,
                    timeout=5,
                    xonxoff = False,
                    rtscts = False,
                    bytesize = serial.EIGHTBITS,
                    parity = serial.PARITY_NONE,
                    stopbits = serial.STOPBITS_ONE)
            #s = input('Enter AT command --> ')
            #print ('AT command = ' + s)
            self.ser.write(bytes('AT+CGMI' + '\r\n'))
            self.ser.timeout = 1
            self.ser.write('AT+CGMM' + '\r\n')
            self.ser.timeout = 1
            response = self.ser.read(999)
            print(response)
            self.lineEdit_2.setText(response)

    except serial.SerialException:
        self.lineEdit_2.setText("could not connect to phone")
        return None

    def check_phone(self):
        self.ser = serial.Serial('/dev/ttyACM0', 
                     460800, 
                     timeout=5, 
                     xonxoff = False,   
                     rtscts = False, 
                     bytesize = serial.EIGHTBITS, 
                     parity = serial.PARITY_NONE, 
                     stopbits = serial.STOPBITS_ONE)

    def sendMessage(self):
        self.ser.write('ATZ\r')
        time.sleep(1)
        self.ser.write('AT+CMGF=1\r')
        time.sleep(1)
        self.ser.write('''AT+CMGS="''' + self.recipient + '''"\r''')
        time.sleep(1)
        self.ser.write(self.content + "\r")
        time.sleep(1)
        self.ser.write(chr(26))
        time.sleep(2)

    def sms_report(self):
        self.ser.write('AT+CMEE=2\r')
        self.ser.timeout = 3
        time.sleep(1)
        self.response2 = self.ser.read(999)
        print(self.response2)
    self.plainTextEdit_2.setPlainText(self.lineEdit.text()+'\nmessage sent successfully'+self.response2())

    def send_sms(self):
        check = self.radioButton.isChecked()
        if check == True: #single sms use
            if not self.lineEdit.text():
                root = tk.Tk()
                root.withdraw()
                tkMessageBox.showwarning("Phone Number Missing!", "Please enter a valid phone number")
                root.destroy()
                root.mainloop()
                return
            if not self.plainTextEdit.toPlainText():
                root = tk.Tk()
                root.withdraw()
                tkMessageBox.showwarning("Message Missing!", "Please enter a text message")
                root.destroy()
                root.mainloop()
                return
            else:
                try:
                    sms = Ui_MainWindow(str(self.lineEdit.text()), str(self.plainTextEdit.toPlainText().encode('ISO-8859-1')))
                    sms.check_phone()
                    sms.sendMessage()
                    repo = self.checkBox.isChecked()
                    if repo == True:
                        sms.sms_report()

                    else:
                        self.plainTextEdit_2.setPlainText(self.lineEdit.text()+'\nmessage sent successfully')
                    sms.disconnectPhone()
                except serial.SerialException:
                    root = tk.Tk()
                    root.withdraw()
                    tkMessageBox.showwarning("NO GSM Connected!", "Plug in your mobile device")
                    root.destroy()
                    root.mainloop()
    else: #sms to contact sheet
        if not self.lineEdit2.text():
            root = tk.Tk()
            root.withdraw()
            tkMessageBox.showwarning("No contact sheet!", "Please add path to contact file")
            root.destroy()
            root.mainloop()
            return
        if not self.plainTextEdit.toPlainText():
            tkm.missing_message()
        else:
            try:
               with open(str(self.lineEdit2.text().encode('utf-8'))) as f:
                if str(self.lineEdit2.text().encode('utf-8')).endswith("csv"): #check whether the file is a .csv file or anything else
                        reader2 = csv.reader(f)
                    reader2.next()
                    linecount = len(zip(*reader2)[0])
                    f.seek(0)
                    reader = csv.reader(f)
                    reader.next()
                    #linecount = len(open(self.lineEdit2.text()).readlines())
                    counter = 0
                    count_all = 0
                        for i, (row) in enumerate(reader):
                        #print (row[0])
                        if not row[0] or row[0].startswith(tuple(ALPHA)): #avoid empty lines
                            counter += 1
                                continue
                        print (row[0])
                        sms = Ui_MainWindow("+491793288636", str(self.plainTextEdit.toPlainText().encode('utf-8')))
                        sms.check_phone()
                        sms.sendMessage()
                        count_all +=1
                        sms.disconnectPhone()
                        self.progressBar.setValue((count_all)*(100/(linecount-counter)))
                        if count_all == linecount-counter:
                            self.plainTextEdit_2.setPlainText('list completed')
                            self.progressBar.setValue(100)
                        else:
                            self.plainTextEdit_2.setPlainText(str(count_all)+'/'+str(linecount-counter)+'\n'+str(row[0])+'\nmessage sent successfully')
                else: #get the shit done for xls or xlsx files, converting them into data.csv
                    x =  xlrd.open_workbook(self.lineEdit2.text()) #hope that works in windoofs
                    worksheet = x.sheet_by_index(0)
                    csvfile = open('data.csv', 'wb')
                        writecsv = csv.writer(csvfile, quoting=csv.QUOTE_ALL)

                        for rownum in xrange(worksheet.nrows):
                            writecsv.writerow(worksheet.row_values(rownum))
                    csvfile.close()
                    time.sleep(2)
                    with open('data.csv', 'rb') as f:
                            reader2 = csv.reader(f)
                        reader2.next()
                        linecount = len(zip(*reader2)[0])
                        f.seek(0)
                        reader = csv.reader(f)
                        reader.next()
                        print(linecount)
                        counter = 0
                        count_all = 0
                            for i, (row) in enumerate(reader):
                            #print (row[0])
                            if not row[0] or row[0].startswith(tuple(ALPHA)): #avoid empty lines
                                counter += 1
                                    continue
                            print (row[0])
                            sms = TextMessage("+491793288636", str(self.plainTextEdit.toPlainText().encode('utf-8')))
                            sms.check_phone()
                            sms.sendMessage()
                            count_all +=1
                            sms.disconnectPhone()
                            self.progressBar.setValue((count_all)*(100/(linecount-counter)))
                            if count_all == linecount-counter:
                                self.plainTextEdit_2.setPlainText('list completed')
                                self.progressBar.setValue(100)
                            else:
                                self.plainTextEdit_2.setPlainText(str(count_all)+'/'+str(linecount-counter)+'\n'+str(row[0])+'\nmessage sent successfully')
            except serial.SerialException:
                root = tk.Tk()
                root.withdraw()
                tkMessageBox.showwarning("NO GSM Connected!", "Plug in your mobile device")
                root.destroy()
                root.mainloop()

if __name__ == "__main__":
    import sys
    app = QtWidgets.QApplication(sys.argv)
    MainWindow = QtWidgets.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())

到目前为止,我尝试为其他课程做的事情是:

lml = Ui_MainWindow()

class MessageBoxes():

    def missing_phone_number(self):
    root = tk.Tk()
    root.withdraw()
    tkMessageBox.showwarning("Phone Number Missing!", "Please enter a valid phone number")
    root.destroy()
    root.mainloop()
    return
    def missing_message(self):
    root = tk.Tk()
    root.withdraw()
    tkMessageBox.showwarning("Message Missing!", "Please enter a text message")
    root.destroy()
    root.mainloop()
    return

class TextMessage():

    def __init__(self, recipient="+491749449785", message="TextMessage.content not set."):
        self.recipient = recipient
        self.content = message

    def missing_phone_number(self): 
        tkm = MessageBoxes()

但是我总是在Ui_MainWindow类中遇到属性问题,例如:AttributeError: Ui_MainWindow instance has no attribute 'lineEdit'

1 个答案:

答案 0 :(得分:0)

你必须建立你的分类 - 让他们以他们共同工作的方式称他们为“mixin课程”。

在Python中,使用内置的super可以轻松实现这一点。 您必须编写__init__方法(可能还有其他方法 - 如果它们存在于所有类中)以获取任意keywoard参数,使用它们使用的内容,并使用super调用其他类__init__。如果所有mixin都这样做,(并且你没有方法或属于namign冲突),你可以使用任何数字os mixins构建任意大的类。

class Base(object):
     pass

class M1(Base):
     """ Methods responsible for foo-things"""
     def __init__(self, **kwargs):
          self.foo_param1 = kwargs.pop("foo_param1")
          self.foo_param2 = kwargs.pop("foo_param2")
          super(M1, self).__init__(**kwargs)

     # define specific foo methods here:

# repeat for other mixins:

    class M2(Base):
        ...

    class M3(base):
        ...

# declare your main class:

class UI_Main(M1, M2, M3, ...):
    def __init__(self, **kwargs):
          super(Ui_Main, self).__init__(**kwargs)

(你真的应该使用Python3.x,在这种情况下,你可以使用super().__init__(**kwargs),而不是硬编码当前的类名。)