首页 > 解决方案 > 我有 2 个组合框(comboBox_1,comboBox_2)comboBox_1 并用正确的数据填充组合框_2

问题描述

from PyQt5 import QtCore, QtGui, QtWidgets


class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(711, 425)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.lineEdit_1 = QtWidgets.QLineEdit(self.centralwidget)
        self.lineEdit_1.setGeometry(QtCore.QRect(110, 110, 200, 40))
        font = QtGui.QFont()
        font.setPointSize(18)
        font.setBold(True)
        font.setWeight(75)
        self.lineEdit_1.setFont(font)
        self.lineEdit_1.setObjectName("lineEdit_1")
        self.lineEdit_2 = QtWidgets.QLineEdit(self.centralwidget)
        self.lineEdit_2.setGeometry(QtCore.QRect(390, 110, 200, 40))
        font = QtGui.QFont()
        font.setPointSize(18)
        font.setBold(True)
        font.setWeight(75)
        self.lineEdit_2.setFont(font)
        self.lineEdit_2.setObjectName("lineEdit_2")
        self.label_2 = QtWidgets.QLabel(self.centralwidget)
        self.label_2.setGeometry(QtCore.QRect(340, 110, 31, 31))
        font = QtGui.QFont()
        font.setPointSize(28)
        font.setBold(True)
        font.setWeight(75)
        self.label_2.setFont(font)
        self.label_2.setObjectName("label_2")
        self.comboBox_2 = QtWidgets.QComboBox(self.centralwidget)
        self.comboBox_2.setGeometry(QtCore.QRect(110, 170, 481, 40))
        font = QtGui.QFont()
        font.setPointSize(18)
        font.setBold(True)
        font.setWeight(75)
        self.comboBox_2.setFont(font)
        self.comboBox_2.setObjectName("comboBox_2")
        self.label_3 = QtWidgets.QLabel(self.centralwidget)
        self.label_3.setGeometry(QtCore.QRect(8, 260, 101, 31))
        font = QtGui.QFont()
        font.setPointSize(16)
        font.setBold(True)
        font.setWeight(75)
        self.label_3.setFont(font)
        self.label_3.setObjectName("label_3")
        self.quitBtn = QtWidgets.QPushButton(self.centralwidget)
        self.quitBtn.setGeometry(QtCore.QRect(547, 320, 121, 51))
        font = QtGui.QFont()
        font.setPointSize(16)
        font.setBold(True)
        font.setWeight(75)
        self.quitBtn.setFont(font)
        self.quitBtn.setObjectName("quitBtn")
        self.clearBtn = QtWidgets.QPushButton(self.centralwidget)
        self.clearBtn.setGeometry(QtCore.QRect(400, 320, 121, 51))
        font = QtGui.QFont()
        font.setPointSize(16)
        font.setBold(True)
        font.setWeight(75)
        self.clearBtn.setFont(font)
        self.clearBtn.setObjectName("clearBtn")
        self.formula_lbl = QtWidgets.QLabel(self.centralwidget)
        self.formula_lbl.setGeometry(QtCore.QRect(107, 260, 561, 31))
        font = QtGui.QFont()
        font.setPointSize(14)
        font.setBold(True)
        font.setWeight(75)
        self.formula_lbl.setFont(font)
        self.formula_lbl.setText("\tFahrenheit = 9/5 * Celcius + 32")
        self.formula_lbl.setObjectName("formula_lbl")
        self.comboBox_1 = QtWidgets.QComboBox(self.centralwidget)
        self.comboBox_1.setGeometry(QtCore.QRect(110, 50, 481, 40))
        font = QtGui.QFont()
        font.setPointSize(18)
        font.setBold(True)
        font.setWeight(75)
        self.comboBox_1.setFont(font)
        self.comboBox_1.setLayoutDirection(QtCore.Qt.LeftToRight)
        self.comboBox_1.setObjectName("comboBox_1")
        self.label_1 = QtWidgets.QLabel(self.centralwidget)
        self.label_1.setGeometry(QtCore.QRect(250, 0, 211, 32))
        font = QtGui.QFont()
        font.setPointSize(18)
        font.setBold(True)
        font.setWeight(75)
        self.label_1.setFont(font)
        self.label_1.setLayoutDirection(QtCore.Qt.LeftToRight)
        self.label_1.setTextFormat(QtCore.Qt.RichText)
        self.label_1.setObjectName("label_1")
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 711, 30))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

        #   When quitBtn is clicked quit app
        self.quitBtn.clicked.connect(QtWidgets.qApp.quit)

        """ When clearBtn is clicked lineEdit_1 and lineEdit_2 are cleared """
        self.clearBtn.clicked.connect(self.lineEdit_1.clear)
        self.clearBtn.clicked.connect(self.lineEdit_2.clear)

        #   Add items to combobox_1
        # self.comboBox_1.addItem("Temperature Conversion") # comboBox_1 Index 0
        # self.comboBox_1.addItem("Speed Conversion")      # comboBox_1 Index 1
        self.comboBox_1.addItems(("Temperature", "Speed"))


        #   Add items temperature Items to combobox_2
        self.comboBox_2.addItem("Celsius  to  Fahrenheight")    # comboBox_2 Index 0
        self.comboBox_2.addItem("Fahrenheight  to  Celsius")    # comboBox_2 Index 1
        self.comboBox_2.addItem("Kelvin  to  Fahrenheight")     # comboBox_2 Index 2
        self.comboBox_2.addItem("Fahrenheight  to  Kelvin")     # comboBox_2 Index 3
        self.comboBox_2.addItem("Celsius  to  Kelvin")          # comboBox_2 Index 4
        self.comboBox_2.addItem("Kelvin  to  Celsius")          # comboBox_2 Index 5
        #  Add Speed Items to comboBox_2
        self.comboBox_2.addItem("Miles per hour to Kilometer")  # comboBox_2 Index 6
        self.comboBox_2.addItem("Kilometer to Miles per hour")  # comboBox_2 Index 7
        #---------------------------------------------------------------------

        """ Checks if the current comboBox_1 selection has changed """
        self.comboBox_1.currentIndexChanged.connect(self.combobox1_changed,
        self.comboBox_1.currentIndex())
        self.comboBox_1.setCurrentIndex(0)




        """ Checks if the current comboBox_2 selection has changed """
        self.comboBox_2.currentIndexChanged.connect(self.combobox2_changed,
        self.comboBox_2.currentIndex())
        self.comboBox_2.setCurrentIndex(0)




    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "Conversion App"))
        self.label_2.setText(_translate("MainWindow", "="))
        self.label_3.setText(_translate("MainWindow", "<html><head/><body><p><span style=\" color:#ff5500;\">Formula:</span></p></body></html>"))
        self.quitBtn.setText(_translate("MainWindow", "Quit"))
        self.clearBtn.setText(_translate("MainWindow", "Clear"))
        self.label_1.setText(_translate("MainWindow", " "))

        #   This is for my reference from my CLI app
        """ function to convert celcius to fahrenheit """
        """ Celsius = Index 1 """
    # def convert_to_fahrenheit():
    #     celcius_formula = "fahrenheit = 9/5 * celcius + 32"
    #     self.formula_lbl.additem(celcius_formula)
    #     try:
    #         celcius = float(self.lineEdit_1)
    #         fahrenheit = 9/5 * celcius + 32

    #     except ValueError:
    #         print("Please enter numbers only.\n")
    #         return convert_to_fahrenheit()
    #     else:
    #         return self.lineEdit_2.addItem(str(round(fahrenheit, 1)))          
    #     convert_to_fahrenheit()

我想在 comboBox_1 中选择一个项目并使用正确的数据填充 comboBox_2 以供我选择

标签: pythonpyqtpyqt5qcombobox

解决方案


首先,您似乎是在 Qt Designer 中设计您的 GUI,然后直接编辑导出的 .py 文件。这几乎总是一个坏主意,因为如果您以后决定在 Qt Designer 中更新您的 GUI,当您重新导出 GUI 时,对 .py 文件的任何更改都将丢失。更好的方法是保持导出的 .py 文件完整,然后将其导入另一个 python 文件,您可以使用它来设置 .py 的实例QMainWindow。一种常见的方法是创建一个单独的类,该类继承自基本小部件(QMainWindow在本例中)和 UI 类('Ui_MainWindow'),并在其中设置所需的信号和插槽。

至于回答实际问题:为了在组合框 1 中选择项目时动态更改组合框 2 中的项目,您可以使用字典,将组合框 1 中的每个项目映射到组合框 2 中相应的项目列表。您然后可以使用第二个字典来存储每个可能的公式。这有一个额外的好处,即您不需要一长串 if-elif 语句来计算结果。

举个例子,假设Ui_MainWindow.py是从 Qt Designer 导出的 python 文件,那么主文件可能类似于

from PyQt5 import QtWidgets, QtCore
from Ui_MainWindow import Ui_MainWindow


class MyMainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
    def __init__(self):
        super().__init__()
        # use Ui_MainWindow.setupUi to setup ui
        self.setupUi(self)

        #   connect quitBtn.clicked and clearBtn.clicked as before
        self.quitBtn.clicked.connect(QtWidgets.qApp.quit)
        self.clearBtn.clicked.connect(self.lineEdit_1.clear)
        self.clearBtn.clicked.connect(self.lineEdit_2.clear)

        #   add items to combobox 1
        self.comboBox_1.addItems(("Temperature", "Speed"))

        #   dict for storing items in combobox 2 corresponding to items in combobox 1
        self.combobox2_dict = {
            'Temperature': ["Celsius  to  Fahrenheit", "Fahrenheight  to  Celsius",
                            "Kelvin  to  Fahrenheit", "Fahrenheit  to  Kelvin",
                            "Celsius  to  Kelvin", "Kelvin  to  Celsius"],
            'Speed': ["Miles per hour to Kilometer per hour", "Kilometer per hour to Miles per hour"]}

        self.transformation_dict = {
            "Celsius  to  Fahrenheit": (lambda T: 9 / 5 * T + 32, 'fahrenheit = 9/5 * celsius + 32'),
            "Fahrenheight  to  Celsius": (lambda T: (T - 32) * 5 / 9, 'celsius = 5/9 * (fahrenheit - 32)'),
            "Kelvin  to  Fahrenheit": (lambda T: 9 / 5 * (T - 273.15) + 32, 'fahrenheit = ... kelvin'),
            "Fahrenheit  to  Kelvin": (lambda T: (T - 32) * 5 / 9 + 273.15, 'kelvin = ... fahrenheit'),
            "Celsius  to  Kelvin": (lambda T: T + 273.15, 'kelvin = celsius + 273.15'),
            "Kelvin  to  Celsius": (lambda T: T - 273.15, 'celsius = kelvin - 273.15'),
            "Miles per hour to Kilometer per hour": (lambda v: v*1.60934, 'miles/h = 1.60934 * km/h'),
            "Kilometer per hour to Miles per hour": (lambda v: v/1.60934, 'km/h = 0.62137 * miles/h') }

        # connect signals to slots for updating combobox 2, the formula label and calculating the result.
        self.comboBox_1.currentTextChanged.connect(self.combobox1_changed)

        # reset label and recalculate result when comboBox_2 changes
        self.comboBox_2.currentTextChanged.connect(self.calculate_result)
        self.comboBox_2.currentTextChanged.connect(self.set_formula_label)

        # recalculate result when lineEdit_1 changes
        self.lineEdit_1.textChanged.connect(self.calculate_result)

        # initialize formula label
        self.comboBox_1.currentTextChanged.emit(self.comboBox_1.currentText())

    def combobox1_changed(self, text):
        blocked = self.comboBox_2.blockSignals(True)
        self.comboBox_2.clear()
        self.comboBox_2.addItems(self.combobox2_dict.get(text, []))
        self.comboBox_2.blockSignals(blocked)
        self.comboBox_2.setCurrentIndex(0)
        self.comboBox_2.currentTextChanged.emit(self.comboBox_2.currentText())

    def set_formula_label(self, text):
        formula = self.transformation_dict[text][1]
        self.formula_lbl.setText(formula)

    def calculate_result(self):
        # Attempt to calculate result by reading text from self.lineEdit_1 and extracting the
        # transformation function from self.transformation_dict
        try:
            # retrieve transformation function and formula as string from dictionary
            func = self.transformation_dict[self.comboBox_2.currentText()][0]
            val0 = float(self.lineEdit_1.text())
            val1 = func(val0)
            self.lineEdit_2.setText(f'{val1:0.2f}')
        except:
            self.lineEdit_2.setText('')



if __name__ == "__main__":
    app = QtWidgets.QApplication([])
    win = MyMainWindow()
    win.show()
    app.exec()

推荐阅读