Есть ли способ проверить, открыто ли окно PyQt5, и соответственно задержать другой экземпляр? - PullRequest
0 голосов
/ 09 апреля 2020

Я новичок с 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)

Ответы [ 2 ]

0 голосов
/ 09 апреля 2020

Некоторое дополнение к eyllanes c:

Кажется, вы хотите инкапсулировать ваше выполнение qt-приложения в функцию уведомлений и подразумеваете, что оно неблокирующее , которое не происходит, так как QT main l oop выполняется в главном потоке. Также вы не можете запустить приложение 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 голосов
/ 09 апреля 2020

Проблема в том, что вы используете exit(), который не определен, вы должны использовать sys.exit(), но это все еще ошибка, так как с этой функцией полное приложение будет закрыто, поскольку это его функция, вместо этого вы просто должны закрыть QApplication:

# ...
class SimpleRoundedCorners(QWidget):
    # ...
    def exeunt(self):
        <b>QApplication.quit()</b>
    # ...
# this is the function
def notification(title, minutes):
    app = QApplication(sys.argv)
    alldone = SimpleRoundedCorners(title, minutes)
    <b>app.exec_()</b>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...