【问题标题】:PyQt5 GUI Structure advice needed需要 PyQt5 GUI 结构建议
【发布时间】:2017-02-28 09:54:20
【问题描述】:

我正在为用户界面编写程序。我对 Qt 很陌生,但我很喜欢使用它,特别感谢 Qt 设计师。该程序应如下所示:它有一个带有 2 个选项卡的主窗口。第一个选项卡是登录,带有用户/密码字段和两个按钮,“登录”和“退出”。 “退出”当然会退出应用程序,“登录”会尝试向服务器发送 SOAP 请求以进行登录。如果不成功,将显示一个带有错误的弹出窗口。如果成功,将显示带有成功消息的弹出窗口,并激活并显示 Tab2,用户可以在其中插入一些数据(组合框的值取决于程序连接到服务器后下载的某些表)。这是代码的精简版:

class Ui_PopupError(object):
    def setupUi(self, Dialog):
        Dialog.setObjectName("Dialog")
        Dialog.resize(322, 101)
        self.label = QtWidgets.QLabel(Dialog)
        self.label.setGeometry(QtCore.QRect(60, 20, 221, 16))
        self.label.setObjectName("label")
        self.pushButton = QtWidgets.QPushButton(Dialog)
        self.pushButton.setGeometry(QtCore.QRect(120, 60, 75, 23))
        self.pushButton.setObjectName("pushButton")
        self.retranslateUi(Dialog)
        self.pushButton.clicked.connect(Dialog.reject)
        QtCore.QMetaObject.connectSlotsByName(Dialog)
    def retranslateUi(self, Dialog):
        _translate = QtCore.QCoreApplication.translate
        Dialog.setWindowTitle(_translate("Dialog", "Dialog"))
        self.label.setText(_translate("Dialog", "Wrong Username or Password. Try Again"))
        self.pushButton.setText(_translate("Dialog", "Ok"))
class Ui_PopupSuccess(object):
    def setupUi(self, Dialog):
        Dialog.setObjectName("Dialog")
        Dialog.resize(322, 101)
        self.label = QtWidgets.QLabel(Dialog)
        self.label.setGeometry(QtCore.QRect(60, 20, 221, 16))
        self.label.setObjectName("label")
        self.pushButton = QtWidgets.QPushButton(Dialog)
        self.pushButton.setGeometry(QtCore.QRect(120, 60, 75, 23))
        self.pushButton.setObjectName("pushButton")
        self.retranslateUi(Dialog)
        self.pushButton.clicked.connect(Dialog.accept)
        QtCore.QMetaObject.connectSlotsByName(Dialog)
    def retranslateUi(self, Dialog):
        _translate = QtCore.QCoreApplication.translate
        Dialog.setWindowTitle(_translate("Dialog", "Dialog"))
        self.label.setText(_translate("Dialog", "Successfully connected."))
        self.pushButton.setText(_translate("Dialog", "Ok"))

class Ui_MainWindow(object):
    def LoginMacro(self):
        Username = self.Usernamefield.text()
        Password = self.Passwordfield.text()
        req = urllib.request.Request("server")
        body = SOAPBody
        response = urllib.request.urlopen(req, body)
        try:
            soup = BeautifulSoup(response.read(), 'html.parser')
            testo = soup.get_text().strip()
            tree = ET.fromstring(testo)
            sessionid = tree.attrib['sessionid']
            self.popup = QtWidgets.QDialog()
            self.popupui = Ui_PopupSuccess()
            self.popupui.setupUi(self.popup)
            self.popup.show()
            self.tabWidget.setCurrentIndex(1)
            self.Recap_Tab.setEnabled(True)
        except:
            self.popup = QtWidgets.QDialog()
            self.popupui = Ui_PopupError()
            self.popupui.setupUi(self.popup)
            self.popup.show()
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(798, 867)
        #MainWindow created with QT Designer (long code...)
        self.Exit.clicked.connect(MainWindow.close)
        self.Login.clicked.connect(self.LoginMacro)
        #This is an example of the value which should feed the combobox:
        self.Handling_Type.addItems(REF_UDF_VALUES['udf_reference_value'][REF_UDF_VALUES['udf_cd']=='Handling Type'])
    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        #Retranslate created with Qt designer....(cut)

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_())

我只是想问你这样做是否正确。特别是,我很难理解将执行“真实”事情(与服务器通信)的代码放在哪里。例如,我将登录代码放在 MainWindow 类中,但我不确定这是否有效,因为我需要从该代码中捕获 jsessionid 以便运行另一个下载表的代码。我应该把这个放在哪里?如果我把它放在代码的“尝试”部分,它会告诉我,当它尝试初始化主窗口中的组合框时,它找不到引用表。我知道,我是个烂摊子! :)

谢谢你,很抱歉这个问题太长了!

【问题讨论】:

    标签: python user-interface pyqt pyqt5


    【解决方案1】:

    与您的后端的通信应该与您的 GUI 定义分开。我创建了一个名为API 的单独类来处理请求/响应,并创建一个API 实例供我的QMainWindow 使用。下面是一个示例,我们希望使用用户列表填充 QComboBox

    class MainWindow(QMainWindow):
        def __init__(self, parent=None):
            super(MainWindow, self).__init__(parent)
            self.ui = Ui_MainWindow()
            self.ui.setupUi(self)
    
            self.api = API()
    
            users = self.api.get_users()
            self.user_widget = self.ui.userCombo
            self.user_widget.setModel(UserListModel(users, self))
    
    class API:
        def __init__(self):
            self.base_url = 'http://localhost:5000/api'
            self.users_url = '/users'
            self.timeout = 5
    
        def get_users(self):
            try:
                r = requests.get(self.base_url + self.users_url, timeout=self.timeout)
            except ConnectionError:
                print("Could not connect to API")
                return API.make_default_user_list()
    
            users = r.json(object_hook=API.api_hook_handler)
    
            return users
    

    如您所见,MainWindow 不关心对用户数据的请求是成功还是失败。无论哪种方式,api.get_users() 都会返回 MainWindow 可以使用的东西。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-16
      • 2011-05-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-26
      相关资源
      最近更新 更多