2017-02-28 4 views
0

사용자 인터페이스 용 프로그램을 작성 중입니다. 나는 Qt를 처음 접했지만 Qt 디자이너 덕분에 그것을 즐기고있다. 프로그램은 다음과 같이 진행되어야합니다 : 2 개의 탭이있는 메인 윈도우가 있습니다. 첫 번째 탭은 사용자/암호 필드와 두 개의 "로그인"및 "종료"버튼이있는 로그인입니다. "Exit"는 물론 앱을 종료 할 것이고, "Login"은 로그인 할 서버에 SOAP 요청을 보내려고 시도 할 것입니다. 실패 할 경우, 오류가있는 K 업이 표시됩니다. 성공하면 성공 메시지가 표시된 팝업이 표시되고 Tab2가 활성화되어 표시됩니다. 사용자는 콤보 상자와 함께 일부 값 (프로그램이 서버에 연결되면 프로그램이 다운로드하는 테이블에 따라 값이 달라짐)을 삽입 할 수 있습니다. 다음은 코드 트림 된 버전입니다.PyQt5 GUI 구조 어드바이스가 필요합니다.

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를 캡처해야하므로이 코드가 작동하는지 잘 모르겠습니다. 이걸 어디에 두어야합니까? 코드의 "try"부분에 넣으면 메인 윈도우에서 콤보 박스를 초기화하려고 할 때 참조 테이블을 찾을 수 없다는 것을 알려줍니다. 나도 알아, 난 엉망이야! :)

감사합니다. 오랜 질문에 사과드립니다!

답변

1

백엔드와의 통신은 GUI 정의와 분리되어야합니다. API이라는 별도의 클래스를 만들어 요청/응답을 처리하고 QMainWindow을 사용하기 위해 API 인스턴스를 만듭니다. 당신이 볼 수 있듯이 사용자 데이터에 대한 요청이 성공하거나 실패 할 경우

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 상관하지 않습니다 여기에 우리가 사용자의 목록이있는 QComboBox을 채울하고 싶은 예입니다. 어쨌든 api.get_users()MainWindow에서 사용할 수있는 것을 반환합니다.

관련 문제