PyQt - 通过代码

时间:2017-10-10 14:02:09

标签: python pyqt pyqt5

我想了解在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_starta_range_1_enda_range_2_starta_range_2_endb_range_1_startb_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_starta_range_2_end个变量再次附加到df1(类似于a_range1_start和{ {1}}在a_range_1_end上执行计算,但显示已附加到df1 QLabel。

此外,我希望将a_range_2_sumb_range_1_startb_range_1_end相关联,以及相应的QLabel。

希望这足以描述问题。非常感谢!

1 个答案:

答案 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()方法来访问父主窗口,并且还允许在必要时定义自定义信号。