使用 lambda 函数时弹出 window 不再关闭
Pop up window no longer closes when using lambda function
使用这个问题的答案:
Python: PyQt Popup Window
我能够生成一个带有弹出窗口 window 的按钮的图形用户界面。
我现在想做的是按下弹出窗口中的按钮,然后将命令传递给 MyPopup class 中的函数。这可以使用 lambda 函数轻松完成,但是,当您按下 mainwindow 中的按钮时,弹出窗口 window 不再关闭,并且会创建一个新的弹出窗口实例,从而产生两个弹出屏幕。据我了解,这是由于 lambda 函数产生了一个信号。有没有办法清除此 lambda 函数,以便在按下主按钮时关闭旧实例并加载弹出窗口的新实例?
如果使用 lambda 无法做到这一点,是否有另一种方法可以将变量传递给函数以获得我正在寻找的结果?
以下是一些示例屏幕截图,可以更好地说明我的问题:
运行 弹出窗口中没有 lambda 的脚本
运行 在弹出窗口中使用 lambda 的脚本
这是上一个问题的修改后的弹出代码:
import sys
from PyQt4.Qt import *
class MyPopup(QWidget):
def __init__(self):
QWidget.__init__(self)
self.btn_popup = QPushButton("broken", self)
self.btn_popup.clicked.connect(lambda state, x='lambda prevents refresh': self.function(x))
def function(self, word):
print('Now I dont close',word)
def paintEvent(self, e):
dc = QPainter(self)
dc.drawLine(0, 0, 100, 100)
dc.drawLine(100, 0, 0, 100)
class MainWindow(QMainWindow):
def __init__(self, *args):
QMainWindow.__init__(self, *args)
self.cw = QWidget(self)
self.setCentralWidget(self.cw)
self.btn1 = QPushButton("Click me", self.cw)
self.btn1.setGeometry(QRect(0, 0, 100, 30))
self.connect(self.btn1, SIGNAL("clicked()"), self.doit)
self.w = None
def doit(self):
print ("Opening a new popup window...")
self.w = MyPopup()
self.w.setGeometry(QRect(100, 100, 400, 200))
self.w.show()
class App(QApplication):
def __init__(self, *args):
QApplication.__init__(self, *args)
self.main = MainWindow()
self.main.show()
def main(args):
global app
app = App(args)
app.exec_()
if __name__ == "__main__":
main(sys.argv)
似乎如果 lambda 函数不存在弹出窗口被破坏,通过添加以下内容来验证这一点:
class MyPopup(QWidget):
def __init__(self, i):
[..]
self.destroyed.connect(lambda: print("destroyed"))
在没有 lambda 的情况下,消息被打印出来,而在另一种情况下则没有。所以解决方法是使用deleteLater()
方法手动销毁:
def doit(self):
print ("Opening a new popup window...")
if self.w:
self.w.deleteLater()
self.w = MyPopup()
self.w.setGeometry(QRect(100, 100, 400, 200))
self.w.show()
使用这个问题的答案: Python: PyQt Popup Window 我能够生成一个带有弹出窗口 window 的按钮的图形用户界面。
我现在想做的是按下弹出窗口中的按钮,然后将命令传递给 MyPopup class 中的函数。这可以使用 lambda 函数轻松完成,但是,当您按下 mainwindow 中的按钮时,弹出窗口 window 不再关闭,并且会创建一个新的弹出窗口实例,从而产生两个弹出屏幕。据我了解,这是由于 lambda 函数产生了一个信号。有没有办法清除此 lambda 函数,以便在按下主按钮时关闭旧实例并加载弹出窗口的新实例?
如果使用 lambda 无法做到这一点,是否有另一种方法可以将变量传递给函数以获得我正在寻找的结果?
以下是一些示例屏幕截图,可以更好地说明我的问题:
运行 弹出窗口中没有 lambda 的脚本
运行 在弹出窗口中使用 lambda 的脚本
这是上一个问题的修改后的弹出代码:
import sys
from PyQt4.Qt import *
class MyPopup(QWidget):
def __init__(self):
QWidget.__init__(self)
self.btn_popup = QPushButton("broken", self)
self.btn_popup.clicked.connect(lambda state, x='lambda prevents refresh': self.function(x))
def function(self, word):
print('Now I dont close',word)
def paintEvent(self, e):
dc = QPainter(self)
dc.drawLine(0, 0, 100, 100)
dc.drawLine(100, 0, 0, 100)
class MainWindow(QMainWindow):
def __init__(self, *args):
QMainWindow.__init__(self, *args)
self.cw = QWidget(self)
self.setCentralWidget(self.cw)
self.btn1 = QPushButton("Click me", self.cw)
self.btn1.setGeometry(QRect(0, 0, 100, 30))
self.connect(self.btn1, SIGNAL("clicked()"), self.doit)
self.w = None
def doit(self):
print ("Opening a new popup window...")
self.w = MyPopup()
self.w.setGeometry(QRect(100, 100, 400, 200))
self.w.show()
class App(QApplication):
def __init__(self, *args):
QApplication.__init__(self, *args)
self.main = MainWindow()
self.main.show()
def main(args):
global app
app = App(args)
app.exec_()
if __name__ == "__main__":
main(sys.argv)
似乎如果 lambda 函数不存在弹出窗口被破坏,通过添加以下内容来验证这一点:
class MyPopup(QWidget):
def __init__(self, i):
[..]
self.destroyed.connect(lambda: print("destroyed"))
在没有 lambda 的情况下,消息被打印出来,而在另一种情况下则没有。所以解决方法是使用deleteLater()
方法手动销毁:
def doit(self):
print ("Opening a new popup window...")
if self.w:
self.w.deleteLater()
self.w = MyPopup()
self.w.setGeometry(QRect(100, 100, 400, 200))
self.w.show()