文件“<string>”,第 1 行,位于 <lambda>NameError:名称“self”未定义

问题描述 投票:0回答:2

我尝试使用 lambda 将变量作为名称传递给函数,但是当我运行它时,出现此错误 NameError 中的文件“”,第 1 行:名称“self”未定义,它发生在 show_items 函数中

这里有什么问题我尝试了一切但没有成功?

    from ast import While
from PyQt5 import QtGui, QtWidgets,QtCore
from PyQt5.uic import loadUi
from PyQt5.QtWidgets import QApplication, QMainWindow,QDialog,QLabel,QTableWidget,QTableWidgetItem,QWidget,QListWidget
import sys
import sqlite3
import ctypes
from PyQt5 import Qt
from PyQt5.QtWidgets import QApplication, QMainWindow,QDialog,QLabel,QTableWidget,QTableWidgetItem,QWidget,QListWidget,QGraphicsOpacityEffect
from PyQt5.QtCore import QPropertyAnimation, QPoint, QEasingCurve , QTimer
import time
from time import sleep
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
connection = sqlite3.connect("main.db")
cu = connection.cursor()
class mainapp(QMainWindow):
    def __init__(self):
        super(mainapp, self).__init__()
        loadUi("main.ui", self)
        self.pages.setCurrentIndex(0)
        self.labelShow.setWordWrap(True)
   
        self.menuFrame.move(1100 , 0)
        self.menuFrame_2.move(1100 , 0)
        self.show_items()
        
    def show_items (self):
        cu.execute("SELECT * FROM notes ")
        all = cu.fetchall()
        count = 1
        height = 0
        push_style = "background-color: rgb(249, 167, 183);\nborder : none;"    
        for i in all:
            main_height = height + 120
            # print(i)
            print(type(i[0]))
            exec("nameInfo"+(str(count))+" ="+'(str(i[0]))'+"")
            # print(eval("nameInfo"+(str(count))))
            exec("self.pushButton = QtWidgets.QPushButton(self.infoFrame)")
            eval("self.pushButton.setGeometry(QtCore.QRect(10, height, 655, 110))")
            eval("self.pushButton.setMinimumSize(QtCore.QSize(655, 110))")
            eval("self.pushButton.setMaximumSize(QtCore.QSize(200, 110))")
            eval("self.pushButton.setStyleSheet(push_style)")
            eval("self.pushButton.setText(nameInfo"+(str(count))+")")
            exec("self.pushButton.clicked.connect(lambda: self.show_Id(nameInfo"+'(str(count))'+"))")
            self.pushButton.setObjectName("pushButton")
            
            # self.verticalLayout.addWidget(self.infoFrame)
            height = height + 130
            print(height)
            count = count + 1
        # self.infoFrame.setMaximumHeight(main_height)
        self.infoFrame.setMinimumHeight(main_height)
    def show_Id(self , name):
        print(name)



app = QApplication(sys.argv)
calculator_app = mainapp()
calculator_app.show()

sys.exit(app.exec_())
python pyqt pyqt5
2个回答
0
投票

我无法测试它,但所有问题都可能是因为您使用

exec()
/
eval()
可能会在不知道代码中有
self
的情况下运行代码。

但是你不应该使用单独的变量

nameInfo1
nameInfo2
,而是列出
nameInfo = []
,然后你就不需要
exec()
/
eval()

类似这样的:

   def show_items(self):
        
        connection = sqlite3.connect("main.db")
        cursor = connection.cursor()

        cursor.execute("SELECT * FROM notes")
        
        height = 0
        push_style = "background-color: rgb(249, 167, 183);\nborder : none;"
        
        #self.all_rows = []
        self.all_names = []
        self.all_buttons = []
        
        for row in cursor.fetchall():

            #self.all_rows.append(row)     # <--- keep all rows on list
            self.all_names.append(row[0])  # <--- keep all names on list

            main_height = height + 120
            
            button = QtWidgets.QPushButton(self.infoFrame)
            button.setGeometry(QtCore.QRect(10, height, 655, 110))
            button.setMinimumSize(QtCore.QSize(655, 110))
            button.setMaximumSize(QtCore.QSize(200, 110))
            button.setStyleSheet(push_style)
            
            button.setText(row[0])
            
            button.clicked.connect(lambda value=row[0]: self.show_id(value))  # it needs `value=` when `lambda` is created in `for`-loop
            
            button.setObjectName("pushButton")
            
            self.all_buttons.append(button)  # <--- keep all buttons on list
            
            # self.verticalLayout.addWidget(self.infoFrame)
            height += 130

        # self.infoFrame.setMaximumHeight(main_height)
        self.infoFrame.setMinimumHeight(main_height)

编辑

PyQt
可能还需要将所有按钮保留在列表中。如果您尝试对所有按钮使用相同的变量
self.pushButton
那么它可能只创建最后一个,因为当您为变量
self.pushButton
分配新值时,它可能会从窗口中删除上一个按钮。

当您在

lambda
中使用
for
时,您需要在
value=row[0]
中使用
lambda value=row[0]: ...
。如果直接使用
row[0]
,它不会发送值,而只会引用变量
row
,之后所有函数都将引用相同的
row
(带有最后一个值),并且所有函数都将使用相同的(最后一个)值.


0
投票

不要使用

lambda
,而是使用functools模块的
partial
功能。所以你的代码就变成了

from functools import partial

exec("self.pushButton.clicked.connect(partial(self.show_Id, nameInfo"+'(str(count))'+"))")
© www.soinside.com 2019 - 2024. All rights reserved.