我尝试使用 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_())
我无法测试它,但所有问题都可能是因为您使用
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
(带有最后一个值),并且所有函数都将使用相同的(最后一个)值.
不要使用
lambda
,而是使用functools模块的partial
功能。所以你的代码就变成了from functools import partial
exec("self.pushButton.clicked.connect(partial(self.show_Id, nameInfo"+'(str(count))'+"))")