是否有办法检查PyQt5窗口是否打开并相应地延迟另一个实例?

问题描述 投票:0回答:2

我是Python3和PyQt5的新手。我制作了一个用于显示通知的PyQt5模板。所以最后我有了一个函数[notification()],它可以在屏幕上显示通知。

但是问题是,当我同时调用多个notification()时,仅显示第一个,然后程序退出。 (最后有一个测试用例-请注意只有第一个弹出了]

我是否可以暂停第二个通知,直到第一个通知完成,然后调用该函数(可能使用标志或其他方法)。

import sys
from PyQt5.QtWidgets import QVBoxLayout,QLabel,QDesktopWidget,QWidget,QApplication
from PyQt5.QtGui import QFont
from PyQt5.QtCore import Qt,QTimer

class SpecialBG(QLabel):
    def __init__(self, parent):
        QLabel.__init__(self, parent)
        self.setStyleSheet(
                "color: rgba(237,174,28,100%);"
                "background-color: rgba(247,247,247,95%);"
                "text-align: center;"
                "border-radius: 20px;"
                "padding: 0px;"
                )

class SimpleRoundedCorners(QWidget):
    def __init__(self,title,minutes):
        self.title = title 
        self.minutes = minutes

        super(SimpleRoundedCorners, self).__init__()
        self.initUI()
        QTimer.singleShot(5500, self.exeunt)

    def exeunt(self):
        self.close
        exit()

    def initUI(self):
        winwidth = 650
        winheight = 150

        font = QFont()
        font.setFamily("SF Pro Display")
        font.setPointSize(20)

        font2 = QFont()
        font2.setFamily("SF Pro Display")
        font2.setPointSize(18)

        VBox = QVBoxLayout()
        roundyround = SpecialBG(self)
        VBox.addWidget(roundyround)

        VBox.pyqtConfigure
        self.setLayout(VBox)
        self.setWindowFlags(
                  Qt.FramelessWindowHint
                | Qt.WindowStaysOnTopHint
                | Qt.SplashScreen
                )

        self.setAttribute(Qt.WA_TranslucentBackground, True)

        taskTitle = QLabel(self)
        taskTitle.move(120, 40)
        taskTitle.setFont(font)
        taskTitle.setText(self.title)
        taskTitle.adjustSize()

        timeLeft = QLabel(self)
        timeLeft.move(120, 80)
        timeLeft.setFont(font2)
        timeLeft.setText("in "+str(self.minutes)+" minutes")
        timeLeft.adjustSize()

        self.setGeometry(1260, 5, winwidth, winheight)
        self.setWindowTitle('Simple Rounded Corners')
        self.show()

# this is the function
def notification(title,minutes):
    app = QApplication(sys.argv)
    alldone = SimpleRoundedCorners(title,minutes)
    sys.exit(app.exec_())

# test-cases
notification("notification #1",5)
notification("notification #2",10)
python python-3.x pyqt pyqt5
2个回答
0
投票

对eyllanesc的回答:]

似乎您想将qt-app执行封装在通知函数中,并表示它是non-blocking

,因为QT主循环在主线程中执行,所以这不会发生。您也不能在非主线程中启动QT应用程序(据我所知)

解决方案可能是在单独的线程中为qt-app创建进程,如果当前正在运行另一个线程(例如,通过信号量),则阻止该线程。显示通知后,该进程和线程将终止。

这里是什么样子:

from subprocess import call
import threading

title1 = "notification #1"
title2 = "notification #2"
m1     = 5
m2     = 10

sem = threading.Semaphore(value=1)


def notify_call(title, minutes) :
    sem.acquire()
    call(["python", "show-notify-qt.py", title, str(minutes)])
    sem.release()


def notify(title, minutes) :
    threading.Thread(target=notify_call, args=(title, minutes)).start()


notify(title1, m1)
print("I'm not blocking!")
notify(title2, m2)
print("I'm still not blocking!")

# show-notify-qt.py
from PyQt5.QtWidgets import QVBoxLayout,QLabel,QDesktopWidget,QWidget,QApplication
from PyQt5.QtGui import QFont
from PyQt5.QtCore import Qt,QTimer
import sys


class SpecialBG(QLabel):
    def __init__(self, parent):
        QLabel.__init__(self, parent)
        self.setStyleSheet(
                "color: rgba(237,174,28,100%);"
                "background-color: rgba(247,247,247,95%);"
                "text-align: center;"
                "border-radius: 20px;"
                "padding: 0px;"
                )

class SimpleRoundedCorners(QWidget):
    def __init__(self,title,minutes):
        self.title = title 
        self.minutes = minutes

        super(SimpleRoundedCorners, self).__init__()
        self.initUI()
        QTimer.singleShot(5500, self.exeunt)

    def exeunt(self):
        QApplication.quit()

    def initUI(self):
        winwidth = 650
        winheight = 150

        font = QFont()
        font.setFamily("SF Pro Display")
        font.setPointSize(20)

        font2 = QFont()
        font2.setFamily("SF Pro Display")
        font2.setPointSize(18)

        VBox = QVBoxLayout()
        roundyround = SpecialBG(self)
        VBox.addWidget(roundyround)

        VBox.pyqtConfigure
        self.setLayout(VBox)
        self.setWindowFlags(
                  Qt.FramelessWindowHint
                | Qt.WindowStaysOnTopHint
                | Qt.SplashScreen
                )

        self.setAttribute(Qt.WA_TranslucentBackground, True)

        taskTitle = QLabel(self)
        taskTitle.move(120, 40)
        taskTitle.setFont(font)
        taskTitle.setText(self.title)
        taskTitle.adjustSize()

        timeLeft = QLabel(self)
        timeLeft.move(120, 80)
        timeLeft.setFont(font2)
        timeLeft.setText("in "+str(self.minutes)+" minutes")
        timeLeft.adjustSize()

        self.setGeometry(1260, 5, winwidth, winheight)
        self.setWindowTitle('Simple Rounded Corners')
        self.show()


app = QApplication(sys.argv)
alldone = SimpleRoundedCorners(sys.argv[1], int(sys.argv[2]))
sys.exit(app.exec_())


0
投票

问题是您正在使用未定义的exit(),应使用sys.exit(),但这仍然是一个错误,因为使用该功能将关闭整个应用程序,因为这是其功能,而您只拥有关闭QApplication:

© www.soinside.com 2019 - 2024. All rights reserved.