Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/user-interface/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python PyQt5中的按钮连接有什么问题?_Python_User Interface_Pyqt5 - Fatal编程技术网

Python PyQt5中的按钮连接有什么问题?

Python PyQt5中的按钮连接有什么问题?,python,user-interface,pyqt5,Python,User Interface,Pyqt5,我有一个问题,我无法连接两个按钮之间的实现。在我按下“灰度”按钮并获得灰度图像后,我按下“Canny”按钮,但用户界面突然关闭。 我不知道我的代码出了什么问题 def getImage(self): global fname fname = QFileDialog.getOpenFileName(self, 'Open file', 'C:\\Users\binil-ping\Desktop\CODE',"Image Files (*.jpg *.gif *.bm

我有一个问题,我无法连接两个按钮之间的实现。在我按下“灰度”按钮并获得灰度图像后,我按下“Canny”按钮,但用户界面突然关闭。 我不知道我的代码出了什么问题

def getImage(self):
    global fname
    fname = QFileDialog.getOpenFileName(self, 'Open file', 
       'C:\\Users\binil-ping\Desktop\CODE',"Image Files (*.jpg *.gif *.bmp *.png)")
    pixmap = QPixmap(fname[0])
    self.label.setPixmap(QPixmap(pixmap))
    self.resize(pixmap.width(), pixmap.height())

def Grayscale(self):
    global edges
    edges = cv2.imread(fname[0], 0)
    edges = cv2.GaussianBlur(edges, (5, 5), 0)
    height, width = edges.shape[:2]
    ret,edges = cv2.threshold(edges,150,255,cv2.THRESH_BINARY)
    kernel = np.ones((5,5),np.uint8)
    edges = cv2.morphologyEx(edges, cv2.MORPH_OPEN, kernel)
    edges = cv2.morphologyEx(edges, cv2.MORPH_OPEN, kernel)

    edges = QImage(edges, width, height, QImage.Format_Grayscale8)
    pixmap = QPixmap.fromImage(edges)
    self.label.setPixmap(pixmap)
    self.resize(pixmap.width(), pixmap.height())

def Canny(self):
    edges2 = cv2.imread(edges[0],-1)
    edges2 = cv2.Canny(edges2,180,200)

    edges2 = QImage(edges2, width, height, QImage.Format_Grayscale8)
    pixmap = QPixmap.fromImage(edges2)
    self.label.setPixmap(pixmap)
    self.resize(pixmap.width(), pixmap.height())
规则1:不要使用全局变量

现在来看看真正的答案

PyQt有一个非常非常糟糕、恼人的习惯,就是如果代码中有未捕获的异常,就会崩溃。这使得调试变得很困难。就我个人而言,我在调试时在插槽周围使用了一个装饰器,它在PyQt杀死应用程序之前打印我的异常

导入日志
从functools导入包装
logger=logging.getLogger(_名称__)
#…许多其他代码。。。
def debugFunc(*错误):
def装饰器(func):
@包装(func)
def流道(*args,**kwargs):
尝试:
返回函数(*args,**kwargs)
除了作为错误的错误:
debug(f“函数{func.\uuuuuu name\uuuuuu}引发了一个{err.\uuuuu class\uuuuuuuuuu.\uuuuuuuuuu name\uuuuuu}被忽略。”,
exc_信息=真)
除异常作为错误外:
logger.critical(f“{err.\uuuuu class.\uuuuuu.\uuuuuu name.\uuuuuuuu}-{err}”,exc\u info=True)
回程转轮
返回装饰器
调试时,这允许我忽略某些错误,并将所有其他错误发送到
日志记录系统。如果您自己不使用它并且不愿意开始使用它,您可以导入
回溯
并使用它的函数,而不是我对
记录器
对象的调用

只需将此函数用作最内部的装饰器,如下所示:

@debugFunc()
def Canny(自我):
边2=cv2.imread(边[0],-1)
edges2=cv2.Canny(Edges2180200)
edges2=QImage(edges2,宽度,高度,QImage.Format_灰度8)
pixmap=QPixmap.fromImage(边2)
self.label.setPixmap(pixmap)
self.resize(pixmap.width(),pixmap.height())[在此处输入图像描述][1]

虽然我对cv2不太熟悉,不能肯定地说,但我认为你的问题可能是cv2.Canny。它看起来不像其他cv2函数的命名,如果我是对的,可能会导致AttributeError。

您的代码有很多问题(包括您没有提供一个),其中一些问题解释了崩溃或可能导致另一个崩溃(我用[*]标记了它们):

  • 如前所述,尽可能避免使用全局变量(几乎总是如此),而是使用类属性
  • 您不断地覆盖这些全局变量,使得调试过程中的一切都变得非常混乱;事实上,您正在为numpy数组和QImage使用
  • [*]您正在尝试
    cv2.imread(edges[0],-1)
    ,但不仅imread需要一个字符串,而且由于上一点,在该点上
    edges
    甚至是一个QImage
  • [*]函数范围内未声明某些变量(Canny函数中的宽度/高度)
  • 你应该避免在函数和变量中使用大写的名称,因为它们通常只用于类名和内置常量
  • 在转换回QImage的过程中出现了一些问题,我想这是由于您对数组应用的各种转换(其中一些转换似乎也是不必要的)对格式\u Grayscale8不太友好,也许您应该对此进行更好的研究
这是对您的代码可能的改进。我正在添加小部件创建部分,因为它在原始示例中丢失了

class ShowImage(QWidget):
    def __init__(self):
        QWidget.__init__(self)
        layout = QVBoxLayout(self)
        self.label = QLabel()
        layout.addWidget(self.label)

        self.getImageBtn = QPushButton()
        layout.addWidget(self.getImageBtn)
        self.getImageBtn.clicked.connect(self.getImage)

        self.grayBtn = QPushButton('gray')
        layout.addWidget(self.grayBtn)
        self.grayBtn.clicked.connect(self.grayScale)

        self.cannyBtn = QPushButton('canny')
        layout.addWidget(self.cannyBtn)
        self.cannyBtn.clicked.connect(self.canny)

        self.fileName = None
        self.edges = None

    def getImage(self):
        fname = QFileDialog.getOpenFileName(self, 'Open file', 
           'C:\\Users\binil-ping\Desktop\CODE',"Image Files (*.jpg *.gif *.bmp *.png)")
        if fname[0]:
            self.fileName = fname[0]
            pixmap = QPixmap(self.fileName)
            self.label.setPixmap(pixmap)

    def grayScale(self):
        if not self.fileName:
            return
        edges = cv2.imread(self.fileName, 0)
        edges = cv2.GaussianBlur(edges, (5, 5), 0)
        ret,edges = cv2.threshold(edges, 150, 255, cv2.THRESH_BINARY)
        kernel = np.ones((5, 5), np.uint8)
        edges = cv2.morphologyEx(edges, cv2.MORPH_OPEN, kernel)
        edges = cv2.morphologyEx(edges, cv2.MORPH_OPEN, kernel)

        self.edges = edges
        height, width = edges.shape[:2]
        image = QImage(edges, width, height, QImage.Format_Grayscale8)
        pixmap = QPixmap.fromImage(image)
        self.label.setPixmap(pixmap)

    def canny(self):
        if self.edges is None:
            return
        edges2 = cv2.Canny(self.edges, 180, 200)
        height, width = edges2.shape[:2]

        edges2 = QImage(edges2, width, height, QImage.Format_Grayscale8)
        pixmap = QPixmap.fromImage(edges2)
        self.label.setPixmap(pixmap)

问题是“问题是什么”,而不是“我如何才能找到问题是什么”。虽然你的建议很好,但在我看来,它并不能回答问题中的问题。@musicamante问题是PyQt在崩溃之前不会打印异常,这就是如何解决的方法。即使这不是根本问题,也是阻碍OP进展的问题。这和任何帧质询答案一样,都是一个答案。这取决于异常情况,一般来说,如果错误不是由(Py)Qt本身造成的,python将抛出其回溯,就像在本例中一样,这是一个类型错误,因为imread函数需要一个文件名字符串,而得到了一个QImage。尽管如此,我仍然相信你的建议是一个有用的建议(可以找到一种方法来解释如何使用它,或者最终在评论中链接到问题),但不是一个有用的答案。很抱歉,你不同意,但这是我的观点。我想说PyQt有点内疚,因为它积极地阻止了回溯被打印出来。“但是不同的意见是公平的。”我没有投反对票,但你回答的第一部分是基于一些误解。您描述的行为是正常的,完全是出于设计-请参阅PyQt5文档:。如果您总是在PyQt5程序中设置excepthook,您将永远不会有任何调试问题。有关恢复旧行为的最小示例,请参阅。非常感谢您的代码。顺便说一句,我刚加入论坛几天,所以我在发布问题时犯了错误,谢谢你提醒我。没问题;也许你可以花点时间阅读;记住把这个(或任何)答案标记为被接受,如果它解决了你的问题,并且把你认为有用的答案推倒,或者以任何方式给你一些其他的帮助。谢谢。顺便说一句,我试过你的代码,它成功了。但是“def canny(self)”从“def getImage”中获取图像是因为“self.fileName”,而不是从“def grayScale(self)”中。你能帮我修改一下吗?非常感谢。@NguyễnAnhDuy查看更新的代码。我刚刚在grayScale()函数的末尾创建了一个class属性,然后在canny()中使用它。很抱歉打扰您,但它在canny()中不起作用:(