我知道蛮力的方式来做我想要的但是我很确定有一种更优雅的方式来完成我的任务。所以我正在寻找一种比蛮力方式更好的方法的帮助。
我有一个类似于应用程序的电子表格,网格上有21行和5列。第一行中的第一列只是用户输入的权重值(w1,w2,w3,w4)。第5列对重量值求和。我的工作正常,不需要太多帮助。
第2行到第20行的复杂性。对于每一行,用户在第1列中输入值,然后在第5列中计算行的加权平均值(使用第1行的权重)。例如,对于任何给定的行,如果用户输入的值进入名为va1,va2,va3,va4的QLineEdit小部件,则va_wa = va1 * w1 + va2 * w2 + va3 * w3 + va4 * w4。
在单行代码中很容易做到这一点。但我不确定如何完成另一行,而不是一遍又一遍地复制代码并更改每一行的名称(蛮力方式)。
这是我的代码:
class MyForm(QtGui.QMainWindow):
def __init__(self, parent=None):
super(MyForm,self).__init__(parent)
self.ui=Ui_MainWindow()
self.ui.setupUi(self)
self.ui.mdiArea.addSubWindow(self.ui.subwindow)
self.ui.mdiArea.addSubWindow(self.ui.subwindow_2)
QtCore.QTimer.singleShot(10, lambda: self.ui.mdiArea.setActiveSubWindow(self.ui.mdiArea.subWindowList()[0]))
self.ui.wt1.editingFinished.connect(self.runBoth)
self.ui.wt2.editingFinished.connect(self.runBoth)
self.ui.wt3.editingFinished.connect(self.runBoth)
self.ui.wt4.editingFinished.connect(self.runBoth)
self.ui.ca1.editingFinished.connect(self.waCalc)
self.ui.ca2.editingFinished.connect(self.waCalc)
self.ui.ca3.editingFinished.connect(self.waCalc)
self.ui.ca4.editingFinished.connect(self.waCalc)
def runBoth(self):
self.wtResult()
self.waCalc()
def wtResult(self):
if len(self.ui.wt1.text())!=0:
a=float(self.ui.wt1.text())
else:
a=0
if len(self.ui.wt2.text())!=0:
b=float(self.ui.wt2.text())
else:
b=0
if len(self.ui.wt3.text())!=0:
c=float(self.ui.wt3.text())
else:
c=0
if len(self.ui.wt4.text())!=0:
d=float(self.ui.wt4.text())
else:
d=0
sum=a+b+c+d
self.ui.wt_total.setText(str(sum))
def waCalc(self):
if len(self.ui.ca1.text())!=0:
ca1=float(self.ui.ca1.text())
else:
ca1=0
if len(self.ui.ca2.text())!=0:
ca2=float(self.ui.ca2.text())
else:
ca2=0
if len(self.ui.ca3.text())!=0:
ca3=float(self.ui.ca3.text())
else:
ca3=0
if len(self.ui.ca4.text())!=0:
ca4=float(self.ui.ca4.text())
else:
ca4=0
if len(self.ui.wt1.text())!=0:
wt1=float(self.ui.wt1.text())
else:
wt1=0
if len(self.ui.wt2.text())!=0:
wt2=float(self.ui.wt2.text())
else:
wt2=0
if len(self.ui.wt3.text())!=0:
wt3=float(self.ui.wt3.text())
else:
wt3=0
if len(self.ui.wt4.text())!=0:
wt4=float(self.ui.wt4.text())
else:
wt4=0
wa=(wt1*ca1)+(wt2*ca2)+(wt3*ca3)+(wt4*ca4)
self.ui.ca_wa.setText(str(wa))
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
myapp=MyForm()
myapp.show()
app.exec_()
所以我已经展示了行有ca1,ca2,ca3,ca4,ca_wa的例子。我将如何处理接下来的19行(除了复制wa_Calc代码19次并将变量更改为nx1:4,nx_wa ab1:4,ab_wa,ba1:4,ba_wa ......等等。我知道还有更多行优雅的方法。
答案 0 :(得分:4)
这是非常复杂的,所以我只想给你一个概述和一些指示 如何完成它。
总体概要如下:
Equation
对象来记录小部件之间的功能关系。步骤1.公式类。
创建新的Equation
对象可能如下所示:
eq1 = Equation("wt_total", computeSum, ["wt1", "wt2", "wt3", "wt4"])
eq2 = Equation("ca_wa", computeDot, ["wt1", "wt2", "wt3", "wt4", "ca1", "ca2", "ca3", "ca4"])
computeSum
和computeDor
可能如下所示:
def computeSum(arr):
return sum(arr)
def computDot(arr):
xs = arr[0:3]
ys = arr[4:7]
return sum ([ x*y for (x,y) in zip(xs,ys) ])
Equation
类需要以下插槽/方法:
您需要一个存储所有方程式的地方。在下面的代码中
我使用self.equations
self
是MyForm
对象。
步骤2. - 更新单个等式。
更新单个方程的方法如下:
# update a single equation
def update(self, eq):
args = []
for wname in eq.argWidgets():
val = ...lookup and convert value stored in wname...
args.append(val)
result = eq.compute(args)
# store result in target widget eq.target
步骤3.更新受影响的方程式。
首先,我们开发一种方法来确定所有受影响的方程式:
# return the equations affected by a change in widget wname
def affected(self, wname):
return [ e | if e.affected(wname) for e in self.equations ]
将使用窗口小部件名称调用handleEditingFinished方法:
def handleEditingFinished(self, wname):
eqs = self.affected(wname)
for e in eqs:
self.update(e)
步骤4.连接所有回调。
此代码未经测试,但希望意图明确。
我们只是将所有的editingFinished回调路由到我们的
名为widget的handleEditingFinished
方法作为传递
第一个论点。
from functools import partial
def callback(self, wname):
self.handleEditingFinished(wname)
for e in self.equations:
for wname in e.argWidgets():
w = ... get the widget named wname...
w.editingFinished(partial(callback, self, wname))
答案 1 :(得分:3)
使用列表:
class MyForm(QtGui.QMainWindow):
def __init__(self, parent=None):
super(MyForm,self).__init__(parent)
self.ui=Ui_MainWindow()
self.ui.setupUi(self)
self.ui.mdiArea.addSubWindow(self.ui.subwindow)
self.ui.mdiArea.addSubWindow(self.ui.subwindow_2)
QtCore.QTimer.singleShot(10, lambda: self.ui.mdiArea.setActiveSubWindow(self.ui.mdiArea.subWindowList()[0]))
self.ui_weights = [getattr(self.ui,'wt%d'%i) for i in range(1,5)]
self.ui_cas = [
[getattr(self.ui,'ca%d_%d'%(row,i)) for i in range(1,5)]
for row in range(1,21)
]
self.ui_cawas = [getattr(self.ui,'ca_wa_%d'%row) for row in range(1,21)]
for wt in self.ui_weights:
wt.editingFinished.connect(self.runBoth)
for row in self.ui_cas:
for cell in row:
cell.editingFinished.connect(self.waCalc)
def runBoth(self):
self.wtResult()
self.waCalc()
def wtResult(self):
result = sum(float(wt.text() or 0) for wt in self.ui_weights)
self.ui.wt_total.setText(str(result))
def waCalc(self):
for row, wa in zip(self.ui_cas,self.ui_cawas):
result = sum(
float(ca.text() or 0) * float(wt.text() or 0)
for ca,wt in zip(row, self.ui_weights)
)
wa.setText(str(result))