当我专门双击左键时,Pyqt5 崩溃而没有错误(双右键有效)

Posted

技术标签:

【中文标题】当我专门双击左键时,Pyqt5 崩溃而没有错误(双右键有效)【英文标题】:Pyqt5 Crashes without error when i specifically double left click (double right works) 【发布时间】:2019-09-10 14:17:55 【问题描述】:

我正在用 Python 创建这个应用程序,它与 Outlook 对话并检索有关每个文件夹中的邮件数量和其他一些东西的一些数据,我正在使用 PyQt5 来执行此操作。

但是当我将信号分配给函数时发生了一些奇怪的事情:

self.table_widget.itemDoubleClicked.connect(self.some_function)

如果我双击此项目,一切运行正常。但是,如果我使用 左键单击 来执行此操作,它只会冻结,然后崩溃而没有任何错误屏幕(通常如果您执行程序,当它崩溃时,您可以在后面的控制台上看到一些堆栈,对吗?在这种情况下,实际上什么都没有显示)。

我不确定我使用他的信号是否正确,所以可能有什么...?

无论如何,由于没有发生错误,我尝试打印一些打印内容以查看它会崩溃的位置,但事实证明 t2 屏幕加载得很好,显然当代码返回主循环时它会崩溃.. .?我不知道,我不可能调试那些东西。

我将尝试仅将基本代码放在这里,以便更容易发现错误,但如果这还不够,我可以显示一些细节。

编辑

根据要求,我在下面做了一个可重现的最小示例,它确实以相同的方式崩溃:

from PyQt5.QtCore import QDateTime, Qt, QTimer, pyqtSignal
from PyQt5.QtWidgets import QApplication, QMainWindow, QDialog, QTableWidgetItem
from PyQt5 import uic
import sys, os

class t0(QMainWindow):

    switch_window = pyqtSignal()

    def __init__(self):
        super(t0, self).__init__()
        uic.loadUi(Controller.application_path + r'\UI\t0.ui', self)
        #This .ui file has pretty much a button to click
        self.btn_ok.clicked.connect(self.onButtonClick1)

    def onButtonClick1(self):
        self.switch_window.emit()


class t1(QDialog):    

    switch_window = pyqtSignal()

    def __init__(self, parent=None):
        super(t1, self).__init__(parent)
        uic.loadUi(Controller.application_path + r'\UI\t1.ui', self)
        #This .ui file has a QTableWidget

        self.tw_indi.setColumnCount(1)
        self.tw_indi.setRowCount(1)
        self.tw_indi.setItem(0, 0, QTableWidgetItem("*"))

        self.tw_indi.itemDoubleClicked.connect(self.direcionar_detalhes)


    def direcionar_detalhes(self, item):
        self.switch_window.emit()

class t2(QDialog): 

    switch_window = pyqtSignal(str)

    def __init__(self, parent=None):
        super(t2, self).__init__(parent)
        uic.loadUi(Controller.application_path + r'\UI\t2.ui', self)
        #This .ui file is identical as the t1.ui, just some minor changes        


class Controller():


    controller = None
    #questões técnicas do módulo os com pyinstaller
    if getattr(sys, 'frozen', False):
        application_path = sys.exec_prefix
    else:
        application_path = os.path.dirname(os.path.abspath(__file__))

    tela = None
    app = QApplication(sys.argv)

    def __init__(self):       
        Controller.controller = self
        self.mostra_carregamento()

        sys.exit(Controller.app.exec_())

    def mostra_carregamento(self):
        self.view = t0()
        self.view.switch_window.connect(self.mostra_indicador)
        self.view.show()    
    def mostra_indicador(self):
        self.view.close()
        self.view = t1()
        self.view.switch_window.connect(self.sinal_indicador)
        self.view.show()

    def sinal_indicador(self): 
        self.view.close()
        self.view = t2()
        self.view.show()

if __name__ == '__main__':
    control = Controller()

编辑 2

这是用户界面的链接: https://drive.google.com/file/d/1-iFNaWUGtJ4687nTcTFtb7WRKUL37als/view?usp=drivesdk

【问题讨论】:

成功了!现在好点了吗? 分享.ui的 完成!我想就这些吧? 如果您提供的信息允许我执行您的代码,那么它就足够了,您如何验证它是否足够?创建一个新文件夹,创建仅包含您的问题信息的文件,如果您可以重现您的原始问题,那么如果它是 MRE 【参考方案1】:

问题不在于信号,而是当您想为新窗口重用相同的变量时,您正在消除仍然可见并因此运行的该对象的内存,从而生成未保留的内存访问。解决方法是使用不同的变量名:

class Controller:
    # ...
    def mostra_carregamento(self):
        self.view0 = t0()
        self.view0.switch_window.connect(self.mostra_indicador)
        self.view0.show()

    def mostra_indicador(self):
        self.view0.close()
        self.view1 = t1()
        self.view1.switch_window.connect(self.sinal_indicador)
        self.view1.show()

    def sinal_indicador(self):
        self.view1.close()
        self.view2 = t2()
        self.view2.show()

【讨论】:

工作就像一个魅力!非常感谢!对了,如果我需要重新打开同一个窗口,我该怎么办?

以上是关于当我专门双击左键时,Pyqt5 崩溃而没有错误(双右键有效)的主要内容,如果未能解决你的问题,请参考以下文章

skyline二次开发system.runtime异常

MATLAB抠图

如何在 PyQt5 中通过拖放来绘制矩形并调整其形状

为啥鼠标左键按一下有时会变成双击了?

如何查询oracle表的操作日志记录

在ORACLE 中怎么查看SQL 执行日志