我想了解在PyQt环境中分配值并对许多不同变量进行计算的最佳方法,其中变量已经在QtDesigner ui文件中分配。
变量根据不同的分组命名,并且因为每个组可以有多个变量,所以它们具有反映其顺序的辅助命名。
例如,我有;
{group_name}_range_{number}_start
{group_name}_range_{number}_end
我想知道如何以更Pythonic的方式分配和处理大量这些变量,多次复制此代码并将其打开以防错误。
这是我的Qt ui
文件(保存空间的单行);
<?xml version="1.0" encoding="UTF-8"?><ui version="4.0"><class>MainWindow</class><widget class="QMainWindow" name="MainWindow"><property name="geometry"><rect><x>0</x><y>0</y><width>390</width><height>261</height></rect></property><property name="windowTitle"><string>MainWindow</string></property><widget class="QWidget" name="centralwidget"><widget class="QLineEdit" name="a_range_1_start"><property name="geometry"><rect><x>30</x><y>30</y><width>113</width><height>41</height></rect></property></widget><widget class="QLineEdit" name="a_range_1_end"><property name="geometry"><rect><x>150</x><y>30</y><width>113</width><height>41</height></rect></property></widget><widget class="QLineEdit" name="a_range_2_start"><property name="geometry"><rect><x>30</x><y>80</y><width>113</width><height>41</height></rect></property></widget><widget class="QLineEdit" name="a_range_2_end"><property name="geometry"><rect><x>150</x><y>80</y><width>113</width><height>41</height></rect></property></widget><widget class="QLineEdit" name="b_range_1_start"><property name="geometry"><rect><x>30</x><y>190</y><width>113</width><height>41</height></rect></property></widget><widget class="QLineEdit" name="b_range_1_end"><property name="geometry"><rect><x>150</x><y>190</y><width>113</width><height>41</height></rect></property></widget><widget class="QLabel" name="a_range_1_sum"><property name="geometry"><rect><x>280</x><y>40</y><width>71</width><height>21</height></rect></property><property name="font"><font><family>Arial</family><pointsize>12</pointsize></font></property><property name="text"><string>TextLabel</string></property></widget><widget class="QLabel" name="a_range_2_sum"><property name="geometry"><rect><x>280</x><y>90</y><width>71</width><height>21</height></rect></property><property name="font"><font><family>Arial</family><pointsize>12</pointsize></font></property><property name="text"><string>TextLabel</string></property></widget><widget class="QLabel" name="b_range_1_sum"><property name="geometry"><rect><x>280</x><y>200</y><width>71</width><height>21</height></rect></property><property name="font"><font><family>Arial</family><pointsize>12</pointsize></font></property><property name="text"><string>TextLabel</string></property></widget></widget></widget><resources/><connections/></ui>
我有以下变量a_range_1_start
,a_range_1_end
,a_range_2_start
,a_range_2_end
,b_range_1_start
,b_range_1_end
属于我所述的格式以上。 python代码如下复制问题;
import sys
import pandas as pd
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.uic import loadUiType
qtCreatorFile = r'test.ui'
Ui_MainWindow, QtBaseClass = loadUiType(qtCreatorFile)
class MainApp(QMainWindow, Ui_MainWindow):
def __init__(self, parent=None, *args):
super().__init__()
self.initUI()
def initUI(self, parent=None, *args):
QMainWindow.__init__(self, None)
Ui_MainWindow.__init__(self)
self.df1 = pd.DataFrame({'mynumbers': range(10)},
index=['a','b','c','d','e','f','g','h','i','j'])
self.df2 = pd.DataFrame({'values': range(10, 40)})
self.setupUi(self)
self.show()
self.a_range_1_start.textChanged.connect(self.a_range_1_start_function)
self.a_range_1_end.textChanged.connect(self.a_range_1_end_function)
def a_range_1_start_function(self):
# Print replaces other text functions here for example...
print('start - ' + self.a_range_1_start.text())
self.calc_a_range_1()
def a_range_1_end_function(self):
print('end - ' + self.a_range_1_end.text())
self.calc_a_range_1()
def calc_a_range_1(self):
myvalue = self.df1.loc[self.a_range_1_start.text():self.a_range_1_end.text(),:].mynumbers.sum()
if myvalue > 0:
self.a_range_1_sum.setText('{:,.2f}'.format(myvalue))
if __name__ == "__main__":
app = QApplication(sys.argv)
w = MainApp()
w.show()
sys.exit(app.exec_())
这只是对问题的快速重现,功能和过程并不完全正如我所使用的那样。
最后,我希望将ui中的a_range_2_start
,a_range_2_end
个变量再次附加到df1
(类似于a_range1_start
和{ {1}}在a_range_1_end
上执行计算,但显示已附加到df1
QLabel。
此外,我希望将a_range_2_sum
和b_range_1_start
与b_range_1_end
相关联,以及相应的QLabel。
希望这足以描述问题。非常感谢!
答案 0 :(得分:1)
可能有很多不同的方法可以解决这类问题,但我只想提出一个问题。我们的想法是将多个对象组合成一个,并为它们提供简单,统一的API。这可以为代码重用提供很好的机会,具体取决于对象的分组方式以及现有功能的重叠程度。
这种方法可能有一个明确的Design Pattern名称:Facade Pattern,也许是Mediator Pattern - 我不确定。
无论如何 - 以下是它如何与你的例子一起使用:
class RangeGroup(QObject):
def __init__(self, parent, df, r_start, r_end, r_sum):
super(RangeGroup, self).__init__(parent)
self.df = df
self.range_start = r_start
self.range_end = r_end
self.range_sum = r_sum
self.range_start.textChanged.connect(self.range_start_function)
self.range_end.textChanged.connect(self.range_end_function)
def range_start_function(self):
print('start - ' + self.range_start.text())
self.calc_range()
def range_end_function(self):
print('end - ' + self.range_end.text())
self.calc_range()
def calc_range(self):
myvalue = self.df.loc[self.range_start.text():self.range_end.text(),:].mynumbers.sum()
if myvalue > 0:
self.range_sum.setText('{:,.2f}'.format(myvalue))
class MainApp(QMainWindow, Ui_MainWindow):
def __init__(self, parent=None, *args):
super().__init__()
self.initUI()
def initUI(self, parent=None, *args):
QMainWindow.__init__(self, None)
Ui_MainWindow.__init__(self)
self.setupUi(self)
df1 = pd.DataFrame({'mynumbers': range(10)},
index=['a','b','c','d','e','f','g','h','i','j'])
df2 = pd.DataFrame({'values': range(10, 40)})
self.range_A1 = RangeGroup(
self, df1, self.a_range_1_start,
self.a_range_1_end, self.a_range_1_sum)
self.range_A2 = RangeGroup(
self, df1, self.a_range_2_start,
self.a_range_2_end, self.a_range_2_sum)
self.range_B1 = RangeGroup(
self, df2, self.b_range_1_start,
self.b_range_1_end, self.b_range_1_sum)
self.show()
我已将RangeGropup
类设为QObject
,因此它提供了parent()
方法来访问父主窗口,并且还允许在必要时定义自定义信号。