2017-01-11 2 views
0

Ich habe Probleme mit einer sehr großen Klasse, die ich jetzt versuche aufzuräumen und in Unterklassen aufzuteilen. Allerdings ist mein größtes Problem atm das Einrichten der richtigen Init-Methoden, um Funktionen zwischen den verschiedenen Unterklassen aufrufbar zu machen. Die Idee ist eine Ui_MainWindow-Klasse, die die GUI-Prozesse behandelt. Eine weitere TextMessage-Klasse, die sich mit den AT-Befehlen befasst, und eine dritte MessageBoxes-Klasse, die alle Fehlermeldungen verarbeitet. Wie würde ich die richtige init-Methode für alle Attribute in der setupUi-Funktion benötigen? Da liegt mein größtes Problem. Vielen Dank im Voraus. so weit war so etwas wieEine große Klasse in mehrere Unterklassen aufteilen, __init__ Probleme

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_()) 

Was ich für die anderen Klassen zu tun versucht:

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() 

Aber ich immer bekommen Probleme mit Attributen in der Ui_MainWindow Klasse wie Die große Klasse ist dies hier : AttributeError: Ui_MainWindow instance has no attribute 'lineEdit'

+1

eine Klasse Aufteilen in Unterklassen ist nicht eine gemeinsame Grund für das Erstellen abgeleiteter Klassen in der objektorientierten Programmierung - normalerweise wird dies getan, um die Basisklasse zu spezialisieren -, so dass es schwierig sein wird, Ratschläge zu geben. – martineau

+0

Ist die Einrückung in Ihrem Code identisch mit der Einrückung, die Sie hier angegeben haben? Es sieht so aus, als hätten Sie möglicherweise einen Kopierfehler gemacht. Wenn dies der Fall ist, ist Ihre Einrückung falsch. Sie rufen Mitglieder an, bevor sie zugewiesen wurden, sodass sie nicht existieren. – JackCC

+0

Meinst du jetzt in der TextMessage-Klasse? Oder allgemein? – fahrradlaus

Antwort

0

Sie müssen Ihre geteilten Klassen erstellen - nennen Sie sie "Mixin-Klassen" in einer Weise, die sie kollaborativ arbeiten.

In Python, das ist einfach mit der integrierten super erreicht. Sie müssen die __init__ Methode (und möglicherweise andere - wenn sie über alle Klassen existieren) schreiben, um beliebige keywoard Parameter zu nehmen, konsumieren, was sie verwenden, und rufen Sie die anderen Klassen __init__ mit Super. Wenn alle Mixins das tun (und Sie haben keine Methode oder keinen Namenskonflikt), können Sie beliebig große Klassen mit einer beliebigen Anzahl von Mixins erstellen.

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) 

(Und Sie sollten wirklich Python3.x verwenden, wobei in diesem Fall yu können jus verwenden super().__init__(**kwargs), wihtout hartzucodieren den aktuellen Klassennamen.)

Verwandte Themen