簡體   English   中英

PyQt5 - 在嘗試使用 macOS 關閉 ui 時陷入循環

[英]PyQt5 - stuck in a loop while trying to close ui using macOS

我用 PyQt5 創建了一個 UI。 我可以在 Windows 上使用它並且它工作得很好,但是當我嘗試在 MacOS 上使用它時,我在嘗試關閉它時被卡住了(使用self.close() )。 使用調試器我發現后PyCharm self.close()它跳到app.exec_()並曾進入以關閉它再次執行功能(例如on_later_button_clicked(self) )。 我也已經嘗試過sys.exit(app.exec_())

這是我的代碼:

import os
import sys

from PyQt5 import QtGui, QtWidgets
from PyQt5.QtCore import pyqtSlot
from PyQt5.QtWidgets import QApplication, QDialog
from PyQt5.uic import loadUi

from Modules.database import addNeverID
from Modules.supportedWebsites import getWebsites


def Start():
    m = askForPartnerUrl()
    # m.setFixedSize(500,500)
    m.show()
    return m


class askForPartnerUrl(QDialog):
    def __init__(self):
        super(askForPartnerUrl, self).__init__()
        loadUi('lib/askForPartnerURL.ui', self)
        self.setWindowTitle('Upload')

        current_id = getFromFile("id.txt")

        self.show_id.setText(current_id)
        self.show_origin_url.setText(
            '<a href="' + getFromFile("origin_url.txt") + '">' + getFromFile("origin_url.txt") + '</a>')
        self.show_origin_url.setOpenExternalLinks(True)

        id_beginns = ["1"]
        website_eq = ["1"]

        website_guess_str = "Nicht verfügbar!"

        for i in range(len(id_beginns)):
            if id_beginns[i] in current_id:
                website_guess_str = '<a href="http://' + website_eq[i] + '">' + website_eq[i] + '</a>'
                self.website_guess.setOpenExternalLinks(True)
                break

        self.website_guess.setText(website_guess_str)

        self.save_button.clicked.connect(self.on_save_button_clicked)
        self.later_button.clicked.connect(self.on_later_button_clicked)
        self.never_button.clicked.connect(self.on_never_button_clicked)

        try:
            os.remove('temp/currentObject/partner_url.txt')
        except:
            pass

    @pyqtSlot()
    def on_never_button_clicked(self):
        addNeverID(getFromFile("id.txt"))
        saveToFile("Never-ID", "partner_url.txt")
        self.close()

    def on_later_button_clicked(self):
        saveToFile("Later-ID", "partner_url.txt")
        self.close()

    def on_save_button_clicked(self):

        url_is_valid = False

        for i in getWebsites():
            if i in self.partner_url_input.text():
                url_is_valid = True
                break

        if url_is_valid:
            saveToFile(self.partner_url_input.text(), "partner_url.txt")
            self.close()
        else:
            error_dialog = QtWidgets.QErrorMessage(self)
            error_dialog.setWindowTitle("Eingabe nicht verwertbar")
            error_dialog.showMessage('Die eingegebene URL ist nicht verwendbar! Bitte prüfe deine Eingabe.')


def showGUI():
    app = QApplication(sys.argv)
    app.setStyle('Fusion')
    app.setWindowIcon(QtGui.QIcon('lib/icon.png'))
    window = Start()
    app.exec_()


def saveToFile(content, filename):
    file = open("temp/currentObject/" + filename, "w+")
    file.write(content)
    file.close()


def getFromFile(filename):
    file = open("temp/currentObject/" + filename)
    content = file.read()
    file.close()
    return content

提前謝謝了

原因是,由於您使用的是 uic,它會自動啟用自動連接功能,該功能會根據對象/信號名稱自動檢測函數名稱並連接它們,即使這些函數沒有 Qt 插槽裝飾器

結果是您的插槽實際上將被稱為三次

  1. 沒有任何參數( clicked() );
  2. 使用已checked參數( clicked(bool) ):該參數被 Qt 忽略,因為該函數不接受任何參數,但無論如何都會調用該函數因為沒有為其指定插槽簽名;
  3. 再次使用checked參數,因為您在代碼中手動連接了它;

如果您想繼續使用自動連接,請為該特定功能使用唯一的插槽裝飾器,否則手動連接到使用自動連接命名的功能(可能使用插槽,如果您需要特定簽名),但不要不要兩個都用。

class askForPartnerUrl(QDialog):
    def __init__(self):
        super(askForPartnerUrl, self).__init__()
        loadUi('askForPartnerURL.ui', self)

        # ...

        # remove the following lines:
        # self.save_button.clicked.connect(self.on_save_button_clicked)
        # self.later_button.clicked.connect(self.on_later_button_clicked)
        # self.never_button.clicked.connect(self.on_never_button_clicked)

        # manual connection
        self.later_button.clicked.connect(self.saveLater)

    # using the auto connection; the function doesn't need arguments, so
    # you can ignore the argument type signature
    @pyqtSlot()
    def on_never_button_clicked(self):
        addNeverID(getFromFile("id.txt"))
        # ...

    # with a normal function; in this case no slot decorator is required since
    # you don't have arguments
    def saveLater(self):
        url_is_valid = False
        # ...

PS:它“卡住”的原因可能是由於 Python 在 MacOS 上處理程序結束的方式(默認情況下,在 Qt 中的最后一個窗口關閉后立即發生):在第一次調用close() PyQt 嘗試退出 QApplication(釋放內存等...),但在這樣做的同時,原始點擊事件仍在向剩余的第二個和第三個插槽發送信號的過程中,因此“循環”(但這不是一個實際的循環,並且第三個插槽永遠不會被調用,因為它是第二個阻止所有內容的插槽)。
請注意,這是一個很大的過度簡化,我不是內存使用和低級編程方面的專家,但這基本上是正在發生的事情。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM