在pyqt5中单击登录按钮时获取小部件未定义错误

Posted

技术标签:

【中文标题】在pyqt5中单击登录按钮时获取小部件未定义错误【英文标题】:Getting widget is not defined error when clicking login button in pyqt5 【发布时间】:2021-07-15 09:06:45 【问题描述】:

我在制作按钮以打开不同的 .ui 文件时遇到问题,但我一直遇到一个问题,即未定义“小部件”,然后程序崩溃。

谁能告诉我我的 gotoLogin 可能做错了什么?

以下是我的代码和 ui 文件。

main.py

import sys
from PyQt5.uic import loadUi
from PyQt5 import QtWidgets
from PyQt5.QtWidgets import QDialog, QApplication, QWidget
from PyQt5.QtGui import QPixmap

import sqlite3

# loading welcome screen
class welcomeScreen(QDialog):
    def __init__(self):
        super(welcomeScreen, self).__init__()
        loadUi("welcomeScreen.ui", self)
        self.login.clicked.connect(self.gotoLogin)

    def gotoLogin(self):
        login = loginScreen()
        widget.addWidget(login)
        widget.setCurrentIndex(widget.currentIndex()+1)

class loginScreen(QDialog):
    def __init__(self):
        super(loginScreen, self).__init__()
        loadUi("login.ui",self)
        self.passwordField.setEchoMode(QtWidgets.QLineEdit.Password)
        self.login.clicked.connect(self.loginFunction)

    def loginFunction(self):
        user = self.emailField.text()
        password = self.passwordField.text()

        if len(user)==0 or len(password)==0:
            self.loginError.setText("Please input all the fields.")

        else:
            conn = sqlite3.connect("petData.db")
            cur = conn.cursor()
            query = 'SELECT password FROM login_info WHERE username = \''+user+"\'"
            cur.execute(query)
            result_pass = cur.fetchone()[0]
            if (result_pass == password):
                print("Successfully logged in.")
                self.error.setText("")
            else:
                self.loginError.setText("Invalid Username or Password")

# main
def main():
    app = QApplication(sys.argv)
    welcome = welcomeScreen()
    widget = QtWidgets.QStackedWidget()
    widget.addWidget(welcome)
    widget.setFixedWidth(1200)
    widget.setFixedHeight(800)
    widget.show()
    try:
        app.exec_()
        #sys.exit(app_exec())
    except:
        print("Exiting gracefully")

if __name__=='__main__':
    app = QApplication(sys.argv)
    main()

welcomeScreen.ui

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>Dialog</class>
 <widget class="QDialog" name="Dialog">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>1200</width>
    <height>800</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>Dialog</string>
  </property>
  <widget class="QWidget" name="bgWidget" native="true">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>1200</width>
     <height>800</height>
    </rect>
   </property>
   <property name="styleSheet">
    <string notr="true">QWidget#bgWidget
background-color:qlineargradient(spread:pad, x1:0.0590406, y1:0.165, x2:1, y2:1, stop:0 rgba(209, 107, 165, 255), stop:1 rgba(255, 255, 255, 255))</string>
   </property>
   <widget class="QLabel" name="label">
    <property name="geometry">
     <rect>
      <x>510</x>
      <y>190</y>
      <width>191</width>
      <height>71</height>
     </rect>
    </property>
    <property name="styleSheet">
     <string notr="true">font: 36pt &quot;MS Shell Dlg 2&quot;; color:rgb(255, 255, 255)
</string>
    </property>
    <property name="text">
     <string>Cat Care</string>
    </property>
   </widget>
   <widget class="QLabel" name="label_2">
    <property name="geometry">
     <rect>
      <x>440</x>
      <y>230</y>
      <width>311</width>
      <height>111</height>
     </rect>
    </property>
    <property name="styleSheet">
     <string notr="true">font: 16pt &quot;MS Shell Dlg 2&quot;; color:rgb(255, 255, 255)</string>
    </property>
    <property name="text">
     <string>Sign in or create a new account</string>
    </property>
   </widget>
   <widget class="QPushButton" name="login">
    <property name="geometry">
     <rect>
      <x>440</x>
      <y>340</y>
      <width>301</width>
      <height>41</height>
     </rect>
    </property>
    <property name="styleSheet">
     <string notr="true">border-radius:20px; 
background-color: rgb(170, 255, 255);
font: 14pt &quot;MS Shell Dlg 2&quot;;
</string>
    </property>
    <property name="text">
     <string>Log in</string>
    </property>
   </widget>
   <widget class="QPushButton" name="create">
    <property name="geometry">
     <rect>
      <x>440</x>
      <y>420</y>
      <width>301</width>
      <height>41</height>
     </rect>
    </property>
    <property name="styleSheet">
     <string notr="true">border-radius:20px; 
background-color: rgb(170, 255, 255);
font: 14pt &quot;MS Shell Dlg 2&quot;;
</string>
    </property>
    <property name="text">
     <string>Create a new account</string>
    </property>
   </widget>
  </widget>
 </widget>
 <resources/>
 <connections/>
</ui>

登录.ui

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>Dialog</class>
 <widget class="QDialog" name="Dialog">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>1200</width>
    <height>800</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>Dialog</string>
  </property>
  <widget class="QWidget" name="bgWidget" native="true">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>1200</width>
     <height>800</height>
    </rect>
   </property>
   <property name="styleSheet">
    <string notr="true">QWidget#bgWidget
background-color:qlineargradient(spread:pad, x1:0.0590406, y1:0.165, x2:1, y2:1, stop:0 rgba(209, 107, 165, 255), stop:1 rgba(255, 255, 255, 255))</string>
   </property>
   <widget class="QLabel" name="label">
    <property name="geometry">
     <rect>
      <x>540</x>
      <y>200</y>
      <width>191</width>
      <height>71</height>
     </rect>
    </property>
    <property name="styleSheet">
     <string notr="true">font: 36pt &quot;MS Shell Dlg 2&quot;; color:rgb(255, 255, 255)
</string>
    </property>
    <property name="text">
     <string>Login</string>
    </property>
   </widget>
   <widget class="QLabel" name="label_2">
    <property name="geometry">
     <rect>
      <x>450</x>
      <y>230</y>
      <width>311</width>
      <height>111</height>
     </rect>
    </property>
    <property name="styleSheet">
     <string notr="true">font: 16pt &quot;MS Shell Dlg 2&quot;; color:rgb(255, 255, 255)</string>
    </property>
    <property name="text">
     <string>Sign in to your existing account</string>
    </property>
   </widget>
   <widget class="QPushButton" name="login">
    <property name="geometry">
     <rect>
      <x>450</x>
      <y>540</y>
      <width>301</width>
      <height>41</height>
     </rect>
    </property>
    <property name="styleSheet">
     <string notr="true">border-radius:20px; 
background-color: rgb(170, 255, 255);
font: 14pt &quot;MS Shell Dlg 2&quot;;
</string>
    </property>
    <property name="text">
     <string>Log in</string>
    </property>
   </widget>
   <widget class="QLabel" name="label_3">
    <property name="geometry">
     <rect>
      <x>510</x>
      <y>130</y>
      <width>191</width>
      <height>71</height>
     </rect>
    </property>
    <property name="styleSheet">
     <string notr="true">font: 36pt &quot;MS Shell Dlg 2&quot;; color:rgb(255, 255, 255)
</string>
    </property>
    <property name="text">
     <string>Cat Care</string>
    </property>
   </widget>
   <widget class="QLineEdit" name="emailField">
    <property name="geometry">
     <rect>
      <x>450</x>
      <y>360</y>
      <width>301</width>
      <height>41</height>
     </rect>
    </property>
    <property name="styleSheet">
     <string notr="true">background-color:rgba(0,0,0,0);
font: 12pt &quot;MS Shell Dlg 2&quot;;</string>
    </property>
   </widget>
   <widget class="QLineEdit" name="passwordField">
    <property name="geometry">
     <rect>
      <x>450</x>
      <y>450</y>
      <width>301</width>
      <height>41</height>
     </rect>
    </property>
    <property name="styleSheet">
     <string notr="true">background-color:rgba(0,0,0,0);
font: 12pt &quot;MS Shell Dlg 2&quot;;</string>
    </property>
   </widget>
   <widget class="QLabel" name="label_4">
    <property name="geometry">
     <rect>
      <x>460</x>
      <y>330</y>
      <width>281</width>
      <height>31</height>
     </rect>
    </property>
    <property name="styleSheet">
     <string notr="true">font: 10pt &quot;MS Shell Dlg 2&quot;;</string>
    </property>
    <property name="text">
     <string>Username</string>
    </property>
   </widget>
   <widget class="QLabel" name="label_5">
    <property name="geometry">
     <rect>
      <x>460</x>
      <y>420</y>
      <width>281</width>
      <height>31</height>
     </rect>
    </property>
    <property name="styleSheet">
     <string notr="true">font: 10pt &quot;MS Shell Dlg 2&quot;;</string>
    </property>
    <property name="text">
     <string>Password</string>
    </property>
   </widget>
   <widget class="QLabel" name="loginError">
    <property name="geometry">
     <rect>
      <x>460</x>
      <y>500</y>
      <width>291</width>
      <height>31</height>
     </rect>
    </property>
    <property name="styleSheet">
     <string notr="true">font: 12pt &quot;MS Shell Dlg 2&quot;; color:red;</string>
    </property>
    <property name="text">
     <string/>
    </property>
   </widget>
  </widget>
 </widget>
 <resources/>
 <connections/>
</ui>

错误

Traceback (most recent call last):
  File "C:\Users\documents\sideProject\pyqt5\CatCare\main.py", line 18, in gotoLogin
    widget.addWidget(login)
NameError: name 'widget' is not defined

【问题讨论】:

【参考方案1】:

在您的代码中,widgetmain 的局部变量。这意味着它只在main 的范围内可见。为了能够在welcomeScreen 中使用它,您必须将其设为全局变量。话虽如此,让一个类修改全局变量并不是一个好主意。在您的情况下,更好的解决方案是完全从welcomeScreen 中删除将小部件添加到堆叠小部件的功能。相反,您可以继承 QStackedWidget 并在其中移动添加小部件和在小部件之间切换的所有功能。子类可能看起来像这样:

class MainWindow(QtWidgets.QStackedWidget):
    def __init__(self):
        super().__init__()
        self.welcome_screen = welcomeScreen()
        self.login_screen = loginScreen()

        self.addWidget(self.welcome_screen)
        self.addWidget(self.login_screen)

        self.setFixedWidth(1200)
        self.setFixedHeight(800)

        self.welcome_screen.login.clicked.connect(self.goto_login)
        self.goto_welcome()

    def goto_login(self):
        self.setCurrentIndex(self.indexOf(self.login_screen))

    def goto_welcome(self):
        self.setCurrentIndex(self.indexOf(self.welcome_screen))

welcomeScreen 就像

class welcomeScreen(QDialog):
    def __init__(self):
        super(welcomeScreen, self).__init__()
        loadUi("welcomeScreen.ui", self)

主要功能会变成

def main():
    app = QApplication(sys.argv)
    widget = MainWindow()
    widget.show()
    try:
        app.exec_()
        #sys.exit(app_exec())
    except:
        print("Exiting gracefully")

【讨论】:

以上是关于在pyqt5中单击登录按钮时获取小部件未定义错误的主要内容,如果未能解决你的问题,请参考以下文章

在小部件中单击按钮后服务未启动

小部件未在 pyqt5 中显示标签

PyQt5,单击按钮后如何打开新窗口

PyQt5 在每个选项卡旁边添加添加和删除小部件按钮

重新启动后,按钮单击时,小组件onUpdate未设置pendingIntent

每次单击登录按钮时都会重建登录小部件