簡體   English   中英

在主窗口位於 python 和 pyqt5 的同一監視器上打開彈出通知

[英]Open popup notification on the same monitor where the mainwindow is in python an pyqt5

在我的QMainWindow中,我有一個按鈕,當我單擊它時,它會在右下角的監視器角打開一個新的QDialog ,並顯示一條成功消息。 現在,如果我將 QMainWindow 移動到另一個監視器(我有 3 個監視器)並單擊按鈕,成功消息彈出窗口將出現在打開QMainWindow的監視器中。 我想要的是彈出消息出現在我的 QMainWindow 實際所在的監視器中。 因此,如果我將QMainWindow移動到監視器 1 並單擊按鈕,成功彈出窗口應在監視器 1 中打開。如果QMainWindow在監視器 2 中,成功彈出窗口應在監視器 2 中打開,與監視器 3 相同。

screenNumber = QDesktopWidget().screenNumber(self)

我可以讀取主窗口所在的屏幕編號。 這很好用。 每次我單擊按鈕時,我都會讀出屏幕編號。 但我沒有找到將屏幕編號設置為我的通知的方法。 有任何想法嗎?

編輯:如果我顯示我的通知 class 可能會有所幫助

筆記.py

from UIs.UI_notify import Ui_Notification
from PyQt5.QtWidgets import QDialog, QApplication, QDesktopWidget
from PyQt5 import QtCore
from PyQt5.QtCore import QRect, QPropertyAnimation, QTimer
import sys
class icon():
checked = "check-circle"
alert = "times-circle"
question = "question-circle"

class notify(QDialog, Ui_Notification):
    def __init__(self, parent=None):
        super(notify,self).__init__(parent)
        self.setupUi(self)
        self.setWindowFlag(QtCore.Qt.WindowType.FramelessWindowHint)
        self.setAttribute(QtCore.Qt.WidgetAttribute.WA_TranslucentBackground)
        ## Some helping stuff
        ############################################################
        parent_sSize = QDesktopWidget().screenGeometry(parent)
        parent_screenNumber = QDesktopWidget().screenNumber(parent)
        sSize = QDesktopWidget().screenGeometry()
        screenNumber = QDesktopWidget().screenNumber()
        print("notification ScreenNumber = " + str(screenNumber))
        print(sSize.width())
        print(sSize.height())
        print("Parents ScreenNumber = " + str(parent_screenNumber))
        print(parent_sSize.width())
        print(parent_sSize.height())
        self.Note_Exit.clicked.connect(self.close)
        ## ScreenSize from parent
        ############################################################
        self.hidedPos = QRect(parent_sSize.width()-self.width()-10,
                              parent_sSize.height()-self.height()+200,
                              self.frameGeometry().width(),
                              self.frameGeometry().height())
        self.showPos = QRect(parent_sSize.width()-self.width()-10,
                              parent_sSize.height()-self.height()-50,
                              self.frameGeometry().width(),
                              self.frameGeometry().height())
    
    def setNote(self, icon=icon.checked, headline="Headline", text="Text"):
        self.icon = icon
        self.headline = headline
        self.text = text
        self.noty_Label_Icon.setText(self.icon)
        self.noty_Label_Headline.setText(self.headline)
        self.noty_Label_Text.setText(self.text)
        self.setGeometry(self.hidedPos)
        self.anim = QPropertyAnimation(self,b"geometry")
        self.anim.setDuration(700)
        self.anim.setEasingCurve(QtCore.QEasingCurve.OutBack)
        self.anim.setEndValue(self.showPos)
        self.anim.start()
        self.notyTimer = QTimer()
        self.notyTimer.singleShot(4000,self.hideNote)
    def hideNote(self):
        self.anim = QPropertyAnimation(self,b"geometry")
        self.anim.setDuration(700)
        self.anim.setEasingCurve(QtCore.QEasingCurve.InOutBack)
        self.anim.setEndValue(self.hidedPos)
        self.anim.start()
        self.anim.finished.connect(self.close)

if __name__ == "__main__":     
    notes = QApplication(sys.argv)
    dialog = notify()
    dialog.show()
    sys.exit(notes.exec())

您不能在構建期間使用小部件的大小,因為此時它具有默認大小(頂級小部件為 640x480,使用父級創建的小部件為 100x30,包括對話框):唯一可靠的選擇是使用sizeHint()或確保已使用adjustSize()正確激活布局。

然后,您不需要屏幕來獲取目標 position,因為父幾何體就足夠了,但您確實需要它來啟動 position,否則對話框將在 Z05B8C74CBD902FBF24ZC1A3下方的任意點“彈出” 請注意,QDesktopWidget 被認為已過時,您應該改用 QScreen。

最后,由於您可能想重用通知,因此應在實際顯示彈出窗口時而不是之前設置 start position。 position 隱藏時也是如此(以防通知可以移動)。

class Notify(QDialog, Ui_Notification):
    def __init__(self, parent):
        super().__init__(parent)
        self.setupUi(self)
        self.setWindowFlag(QtCore.Qt.WindowType.FramelessWindowHint)
        self.setAttribute(QtCore.Qt.WA_TranslucentBackground)

        self.showAnim = QPropertyAnimation(self, b'geometry')
        self.showAnim.setDuration(700)
        self.showAnim.setEasingCurve(QtCore.QEasingCurve.OutBack)

        self.hideAnim = QPropertyAnimation(self, b'geometry')
        self.hideAnim.setDuration(700)
        self.hideAnim.setEasingCurve(QtCore.QEasingCurve.InOutBack)

        self.hideTimer = QTimer(self, singleShot=True)
        self.hideTimer.setInterval(4000)

        self.hideTimer.timeout.connect(self.hideNote)
        self.showAnim.finished.connect(self.hideTimer.start)
        self.hideAnim.finished.connect(self.close)

    def setNote(self, icon=icon.checked, headline="Headline", text="Text"):
        self.icon = icon
        self.headline = headline
        self.text = text
        self.noty_Label_Icon.setText(self.icon)
        self.noty_Label_Headline.setText(self.headline)
        self.noty_Label_Text.setText(self.text)

        self.adjustSize() # important!
        endRect = self.rect()
        center = self.parent().geometry().center()
        endRect.moveCenter(center)
        screen = QApplication.screenAt(center)
        startRect = QRect(endRect)
        startRect.moveTop(screen.geometry().bottom())

        self.setGeometry(startRect)
        self.showAnim.setStartValue(startRect)
        self.showAnim.setEndValue(endRect)
        self.showAnim.start()
        self.show()

    def hideNote(self):
        rect = self.geometry()
        self.hideAnim.setStartValue(rect)
        screen = QApplication.screenAt(rect.center())
        rect.moveTop(screen.geometry().bottom())
        self.hideAnim.setEndValue(rect)
        self.hideAnim.start()


if __name__ == "__main__":     
    notes = QApplication(sys.argv)
    notes.setStyle('fusion')
    w = QMainWindow()
    b = QPushButton('click!')
    w.setCentralWidget(b)
    w.show()
    notify = Notify(w)
    b.clicked.connect(lambda: notify.setNote())
    sys.exit(notes.exec())

請注意,如果您要每次都創建彈出窗口,您還應該設置WA_DeleteOnClose屬性以便在關閉時將其銷毀,否則它將保留在 memory 中。

注意: QTimer.singleShot()是一個 static function,創建一個 QTimer 的實例來使用它是沒有意義的,因為該實例不會被使用,並且無論如何都會創建一個的 QTimer。

謝謝你。 與此同時,我找到了一個適合我的解決方案。 看起來有點臟但有效。 你能告訴我,我的代碼和你的代碼有什么區別嗎? 我為什么要使用你的代碼,除了你是一個更好的程序員;-) 我設置了WA_DeleteOnClose屬性。 很高興知道。 謝謝

筆記.py

from UIs.UI_notify import Ui_Notification
from PyQt5.QtWidgets import QDialog, QApplication
from PyQt5 import QtCore
from PyQt5.QtCore import QRect, QPropertyAnimation, QTimer
import sys
class icon():
    checked = "check-circle"
    alert = "times-circle"
    question = "question-circle"
    clock = "clock"

class notify(QDialog, Ui_Notification):
    def __init__(self, parent=None):
        super(notify,self).__init__(parent)
        self.setupUi(self)
        self.setWindowFlag(QtCore.Qt.WindowType.FramelessWindowHint)
        self.setAttribute(QtCore.Qt.WidgetAttribute.WA_TranslucentBackground)
        self.setAttribute(QtCore.Qt.WidgetAttribute.WA_DeleteOnClose)
        self.setWindowModality(QtCore.Qt.NonModal)
        self.Note_Exit.clicked.connect(self.close)
        self.parent_h = self.parent().geometry().height()
        self.parent_w = self.parent().geometry().width()
        self.parent_x = self.parent().geometry().x()
        self.parent_y = self.parent().geometry().y()
        self.dialog_w = self.width()
        self.dialog_h = self.height()   
        self.setGeometry(self.parent_x+self.parent_w-self.dialog_w-10, self.parent_y+self.parent_h-self.dialog_h+120, self.dialog_w, self.dialog_h)
        ## ScreenSize from parent
        ############################################################
    
    def setNote(self, icon=icon.checked, headline="Headline", text="Text"):
        self.icon = icon
        self.headline = headline
        self.text = text
        self.noty_Label_Icon.setText(self.icon)
        self.noty_Label_Headline.setText(self.headline)
        self.noty_Label_Text.setText(self.text)
        self.anim = QPropertyAnimation(self,b"geometry")
        self.anim.setDuration(700)
        self.anim.setEasingCurve(QtCore.QEasingCurve.OutBack)
        self.anim.setEndValue(QRect(self.parent_x+self.parent_w-self.dialog_w-10, self.parent_y+self.parent_h-self.dialog_h-20, self.dialog_w, self.dialog_h))
        self.anim.start()
        self.notyTimer = QTimer()
        self.notyTimer.singleShot(4000,self.hideNote)
    def hideNote(self):
        self.anim = QPropertyAnimation(self,b"geometry")
        self.anim.setDuration(700)
        self.anim.setEasingCurve(QtCore.QEasingCurve.InOutBack)
        self.anim.setEndValue(QRect(self.parent_x+self.parent_w-self.dialog_w-10, self.parent_y+self.parent_h-self.dialog_h+120, self.dialog_w, self.dialog_h))
        self.anim.start()
        self.anim.finished.connect(self.close)

if __name__ == "__main__":     
    notes = QApplication(sys.argv)
    dialog = notify()
    dialog.show()
    sys.exit(notes.exec())

暫無
暫無

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

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