我遇到了一个非常大的课程,我现在正试图清理并拆分成子类。但是我最大的问题是设置正确的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'
答案 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)
,而不是硬编码当前的类名。)