[英]Creating a back button using PyQt5 in Python
1)我正在嘗試使用 PyQt5 創建一個應用程序。 當登錄成功時,我會進入使用類 Ui_select 創建的選擇頁面。 這工作正常。 但是,當我出於某種原因嘗試使用后退箭頭注銷時,即使我首先運行 gui_select.py 文件,就好像它是主文件一樣,頁面也會崩潰,后退箭頭沒有問題。
2)我使用 Qt Designer 創建了 Windows,但我試圖編輯它們以使其工作而不使用檢查文件是否為 main==> if name == " main ": above app = QtWidgets.QApplication(sys.argv)因為我只希望創建登錄窗口的代碼作為主文件。
*這是登錄頁面的代碼:
from PyQt5 import QtCore, QtGui, QtWidgets
import gui_select
import time, getpass
number = 2
users = {'m': 1} #Test the dictionary tommorow to see if it will work accordingly
class Ui_MainWindow(object):
def openWindow(self, user_id, password):
x = users.get(user_id)
if x == int(password): # Figure out how to make the dictionary work
MainWindow.close()
self.window = QtWidgets.QMainWindow()
self.ui = gui_select.Ui_select()
self.ui.setupUi(self.window)
self.window.show()
else:
self.login.setText("Wrong Password, Please Retry")
time.sleep(1)
self.login.setText("Login")
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(1099, 775)
MainWindow.setStyleSheet("background-color: rgb(4, 112, 54)\n"
"")
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.label_2 = QtWidgets.QLabel(self.centralwidget)
self.label_2.setGeometry(QtCore.QRect(490, 10, 111, 41))
font = QtGui.QFont()
font.setFamily("Broadway")
font.setPointSize(35)
self.label_2.setFont(font)
self.label_2.setStyleSheet("color: rgb(255, 255, 255)")
self.label_2.setObjectName("label_2")
self.groupBox_login_info = QtWidgets.QGroupBox(self.centralwidget)
self.groupBox_login_info.setGeometry(QtCore.QRect(390, 517, 274, 171))
font = QtGui.QFont()
font.setFamily("Bahnschrift Light Condensed")
font.setPointSize(14)
self.groupBox_login_info.setFont(font)
self.groupBox_login_info.setStyleSheet("color: rgb(255, 255, 255)")
self.groupBox_login_info.setObjectName("groupBox_login_info")
self.horizontalLayout = QtWidgets.QHBoxLayout(self.groupBox_login_info)
self.horizontalLayout.setObjectName("horizontalLayout")
self.gridLayout = QtWidgets.QGridLayout()
self.gridLayout.setObjectName("gridLayout")
self.lineEdit_password = QtWidgets.QLineEdit(self.groupBox_login_info)
self.lineEdit_password.setStyleSheet("color: rgb(255, 255, 255)")
self.lineEdit_password.setEchoMode(QtWidgets.QLineEdit.Password)
self.lineEdit_password.setObjectName("lineEdit_password")
self.gridLayout.addWidget(self.lineEdit_password, 1, 1, 1, 1)
self.label_3 = QtWidgets.QLabel(self.groupBox_login_info)
font = QtGui.QFont()
font.setFamily("Bahnschrift Light Condensed")
font.setPointSize(18)
font.setBold(True)
font.setWeight(75)
self.label_3.setFont(font)
self.label_3.setStyleSheet("color: rgb(255, 255, 255)")
self.label_3.setObjectName("label_3")
self.gridLayout.addWidget(self.label_3, 1, 0, 1, 1)
self.label = QtWidgets.QLabel(self.groupBox_login_info)
font = QtGui.QFont()
font.setFamily("Bahnschrift Light Condensed")
font.setPointSize(18)
font.setBold(True)
font.setWeight(75)
self.label.setFont(font)
self.label.setStyleSheet("color: rgb(255, 255, 255)")
self.label.setObjectName("label")
self.gridLayout.addWidget(self.label, 0, 0, 1, 1)
self.lineEdit_user_id = QtWidgets.QLineEdit(self.groupBox_login_info)
self.lineEdit_user_id.setStyleSheet("color: rgb(255, 255, 255)")
self.lineEdit_user_id.setObjectName("lineEdit_user_id")
self.gridLayout.addWidget(self.lineEdit_user_id, 0, 1, 1, 1)
self.login = QtWidgets.QPushButton(self.groupBox_login_info)
font = QtGui.QFont()
font.setFamily("Bahnschrift Light Condensed")
font.setPointSize(14)
self.login.setFont(font)
self.login.setObjectName("login")
self.login.clicked.connect(lambda: self.openWindow(self.lineEdit_user_id.text(), self.lineEdit_password.text()))
self.gridLayout.addWidget(self.login, 2, 0, 1, 2)
self.horizontalLayout.addLayout(self.gridLayout)
self.label_4 = QtWidgets.QLabel(self.centralwidget)
self.label_4.setGeometry(QtCore.QRect(130, 60, 791, 451))
self.label_4.setMaximumSize(QtCore.QSize(791, 471))
self.label_4.setText("")
self.label_4.setPixmap(QtGui.QPixmap("Resource File\Landing page image.png"))
self.label_4.setObjectName("label_4")
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 1099, 26))
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)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.label_2.setText(_translate("MainWindow", "Blu"))
self.groupBox_login_info.setTitle(_translate("MainWindow", "Login info:"))
self.label_3.setText(_translate("MainWindow", "Password:"))
self.label.setText(_translate("MainWindow", "User ID:"))
self.login.setText(_translate("MainWindow", "Login"))
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_())
*這是選項選擇頁面的代碼:
from PyQt5 import QtCore, QtGui, QtWidgets
import gui_login
import os
from PIL import Image
number = 2
this_dir = os.path.abspath(os.path.dirname(__file__))
some_image = os.path.join(this_dir, 'Resource File', 'Back_arrow_image.png')
class Ui_select(object):
def openWindow(self):
select.close()
self.window = QtWidgets.QMainWindow()
self.ui = gui_login.Ui_MainWindow()
self.ui.setupUi(self.window)
self.window.show()
def back_arrow(self):
self.back_button = QtWidgets.QPushButton(self.centralwidget)
self.back_button.setGeometry(QtCore.QRect(770, 30, 221, 81))
self.back_button.setObjectName("back_button")
BlackArrow = Image.open(some_image)
new_image = BlackArrow.resize((1920, 1920))
new_image.save("WhiteArrow.png")
self.back_button.setIcon(QtGui.QIcon("WhiteArrow.png"))
self.back_button.clicked.connect(lambda: self.openWindow())
def setupUi(self, select):
select.setObjectName("select")
select.resize(1090, 600)
select.setStyleSheet("background-color: rgb(4, 112, 54)\n"
"")
self.centralwidget = QtWidgets.QWidget(select)
self.centralwidget.setObjectName("centralwidget")
self.set_parameters = QtWidgets.QPushButton(self.centralwidget)
self.set_parameters.setGeometry(QtCore.QRect(380, 300, 281, 71))
font = QtGui.QFont()
font.setFamily("Bahnschrift Light Condensed")
font.setPointSize(18)
self.set_parameters.setFont(font)
self.set_parameters.setStyleSheet("color: rgb(255, 255, 255)")
self.set_parameters.setObjectName("set_parameters")
self.set_parameters_2 = QtWidgets.QPushButton(self.centralwidget)
self.set_parameters_2.setGeometry(QtCore.QRect(380, 390, 281, 71))
font = QtGui.QFont()
font.setFamily("Bahnschrift Light Condensed")
font.setPointSize(18)
self.set_parameters_2.setFont(font)
self.set_parameters_2.setStyleSheet("color: rgb(255, 255, 255)")
self.set_parameters_2.setObjectName("set_parameters_2")
self.set_parameters_3 = QtWidgets.QPushButton(self.centralwidget)
self.set_parameters_3.setGeometry(QtCore.QRect(380, 210, 281, 71))
font = QtGui.QFont()
font.setFamily("Bahnschrift Light Condensed")
font.setPointSize(18)
self.set_parameters_3.setFont(font)
self.set_parameters_3.setStyleSheet("color: rgb(255, 255, 255)")
self.set_parameters_3.setObjectName("set_parameters_3")
self.label_2 = QtWidgets.QLabel(self.centralwidget)
self.label_2.setGeometry(QtCore.QRect(470, 60, 111, 41))
font = QtGui.QFont()
font.setFamily("Broadway")
font.setPointSize(35)
self.label_2.setFont(font)
self.label_2.setStyleSheet("color: rgb(255, 255, 255)")
self.label_2.setObjectName("label_2")
select.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(select)
self.menubar.setGeometry(QtCore.QRect(0, 0, 1090, 26))
self.menubar.setObjectName("menubar")
self.menuMenu = QtWidgets.QMenu(self.menubar)
self.menuMenu.setObjectName("menuMenu")
select.setMenuBar(self.menubar)
self.back_arrow()
self.statusbar = QtWidgets.QStatusBar(select)
self.statusbar.setObjectName("statusbar")
select.setStatusBar(self.statusbar)
self.menubar.addAction(self.menuMenu.menuAction())
self.retranslateUi(select)
QtCore.QMetaObject.connectSlotsByName(select)
def retranslateUi(self, select):
_translate = QtCore.QCoreApplication.translate
select.setWindowTitle(_translate("select", "MainWindow"))
self.set_parameters.setText(_translate("select", "Set Parameters"))
self.set_parameters_2.setText(_translate("select", "History"))
self.set_parameters_3.setText(_translate("select", "Auto Detect"))
self.label_2.setText(_translate("select", "Blu"))
self.menuMenu.setTitle(_translate("select", "Menu "))
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
select = QtWidgets.QMainWindow()
ui = Ui_select()
ui.setupUi(select)
select.show()
sys.exit(app.exec_())
提前致謝
如果您在 shell/提示上運行代碼,您將看到以下錯誤:
Exception "unhandled NameError"
name 'select' is not defined
File: /tmp/gui_select.py, Line: 14
這是因為select
僅在第二個文件的if __name__
中聲明。
__main__
的重要性當一個 python 文件被加載時,它的主要縮進級別中的所有內容都會被處理,即使在導入腳本時也是如此。
在您的情況下,不會執行第二個文件中__name__
檢查中的內容(因為對於該文件, __name__
實際上是gui_select
),這意味着整個塊將被忽略並且select
不會被創建,因此與上述崩潰錯誤。
if __name__
檢查不僅是一種很好的做法,而且通常也是強制性的。
如果您將該塊中的所有內容移到if
之外,它將在您從主腳本導入文件后立即執行; 結果是,當您啟動第一個腳本時,它將導入第二個腳本,該腳本將完全執行,因此它將創建 QApplication 實例和選擇窗口,然后立即顯示它,直到該窗口關閉為止; 然后它將退出程序(由於sys.exit
調用)而sys.exit
不顯示登錄窗口。
這是非常不鼓勵的,因為它通常會導致大量的問題和誤解(例如在這種情況下),但主要原因是每當您出於任何原因需要再次修改 GUI 時,您都會遇到嚴重的問題來合並您的pyuic 創建的新文件的現有代碼。 作為對官方指南顯示使用Designer (一部分由這些文件中的“警告”提示),這些腳本絕不能手動修改,應始終作為進口。
這是您需要遵循的步驟:
.ui
文件(確保在Designer中select
第二個窗口的對象名稱); from PyQt5 import QtWidgets from gui_login import Ui_MainWindow from gui_select import Ui_select class LoginWindow(QtWidgets.QMainWindow, Ui_MainWindow): def __init__(self): super().__init__() self.setupUi(self) self.login.clicked.connect(self.showSelect) def showSelect(self): user_id = self.lineEdit_user_id.text() password = self.lineEdit_password.text() x = users.get(user_id) if x == int(password): self.close() self.selectWindow = SelectWindow() self.selectWindow.show() else: # this is *wrong*, see below self.login.setText("Wrong Password, Please Retry") time.sleep(1) self.login.setText("Login") class SelectWindow(QtWidgets.QMainWindow, Ui_select): def __init__(self): super().__init__() self.setupUi(self) self.back_button.clicked.connect(self.showLogin) def showLogin(self): self.close() self.loginWindow = LoginWindow() self.loginWindow.show() if __name__ == '__main__': import sys app = QtWidgets.QApplication(sys.argv) loginWindow = LoginWindow() loginWindow.show() sys.exit(app.exec_())
一些考慮:
image = QtGui.QPixmap('path_to_image.png').scaled(width, height, transformMode=QtCore.Qt.SmoothTransformation)
;iconSize()
屬性自動縮放圖標,所以不清楚為什么要將圖像縮放到 1920x1920; 如果要指定更大的尺寸,請使用self.back_button.setIconSize(QtCore.QSize(width, height))
;lambda
;time.sleep(1)
阻塞函數(如第一個文件中的time.sleep(1)
,因為它們不僅會阻止交互,而且最重要的是阻止正確的 GUI 更新/繪制:事實上,您可能會看到按鈕文本不會更新為“錯誤的密碼”文本; 改用 QMessageBox 或連接到更新標簽的插槽的 QTimer : class LoginWindow(QtWidgets.QMainWindow, Ui_MainWindow): # ... def showSelect(self): # ... else: self.login.setText("Wrong Password, Please Retry") self.login.setEnabled(False) QtCore.QTimer.singleShot(2000, self.restoreLogin) def restoreLogin(self): self.login.setText("Login") self.login.setEnabled(True)
self.window
或self.ui
,因為這可能會導致混淆:這些屬性應指代當前的窗口和 ui類實例,如果它們屬於另一個實例,您可能應該使用self.otherWindow
和self.otherUi
類的名稱來命名它們; 這不是程序問題,而是代碼閱讀/審查問題:使用精心挑選的名稱可以提高閱讀和理解能力,這非常重要,即使是您自己的代碼;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.