来自 QWidget 的 PyQt5 通知 [英] PyQt5 notification from QWidget

查看:75
本文介绍了来自 QWidget 的 PyQt5 通知的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想要我自己的来自 PC 手机的通知,比如 notify-senf.我做了弹出窗口小部件,但我无法删除.当我删除它时,仍然有空的地方.我怎样才能做到这一点?此代码是示例.

I want my own notifications from phone on PC, like notify-senf. I do popup widgets, but I can't delete then. When I delete it, there is still empty place. How can I do this? This code is example.

class Notification(QWidget):
    signNotifyClose = QtCore.pyqtSignal(str)

    def __init__(self, parent = None):
        time = datetime.now()
        currentTime = str(time.hour) + ":" + str(time.minute) + "_"
        self.LOG_TAG = currentTime + self.__class__.__name__ + ": "
        super(QWidget, self).__init__(parent)

        self.setWindowFlags(QtCore.Qt.FramelessWindowHint) #убирает заголовок, поверх всех окон (| QtCore.Qt.WindowStaysOnTopHint)
        resolution = QDesktopWidget().screenGeometry(-1)
        screenWidth = resolution.width()
        screenHeight = resolution.height()
        print(self.LOG_TAG + "width: " + str(resolution.width()) + " height: " + str(resolution.height()))
        self.count = 0 # Счетчик уведомлений
        self.timer = 3

        self.vboxMainLayout = QVBoxLayout() # layout contain notifications
        self.move(screenWidth, 0)
        self.setLayout(self.vboxMainLayout)

    def setNotify(self, title, notify):
        count = self.count
        title = QLabel()
        title.setStyleSheet("border: 1px solid #000")
        title.setText(title)
        title.setStyleSheet("font-family: 'Roboto', sans-serif; font-size: 14px; font-weight: bold; padding: 0;")

        text = QLabel()
        text.setText(notify)
        text.setStyleSheet("font-family: 'Roboto', sans-serif; font-size: 12px; font-weight: normal; padding: 0;")

        gridNotify = QGridLayout()
        gridNotify.addWidget(title, 0, 0)
        gridNotify.addWidget(text, 1, 0)

        buttonClose = QPushButton()
        buttonClose.clicked.connect(self.deleteWidgets)
        buttonClose.setIcon(QIcon("res/close1.png"))
        buttonClose.setFlat(False)
        buttonClose.setMaximumWidth(14)
        buttonClose.setMaximumHeight(14)

        gridClose = QGridLayout()
        gridClose.addWidget(buttonClose, 0, 0)

        gridLayoutMain = QGridLayout()
        gridLayoutMain.setColumnStretch(0,1)
        gridLayoutMain.setColumnStretch(0,2)
        gridLayoutMain.setColumnStretch(0,3)
        gridLayoutMain.addLayout(gridClose, 0, 4)
        gridLayoutMain.addLayout(gridNotify, 0, 0)

        self.count += 1

        self.vboxMainLayout.addLayout(gridLayoutMain)
        self.show()
        threading.Timer(2, self.delete, args=(gridLayoutMain,)).start()

    def delete(self, layout):
        for i in reversed(range(layout.count())):
            item = layout.takeAt(i)
            widget = item.widget()
            if widget is not None:
                # widget.deleteLater()
            elif item.layout() is not None:
                print("")
                self.delete(item.layout())

通知

删除后放置

推荐答案

为了简化任务,最好为消息创建一个 Widget,如下所示:

To simplify the task it is better to create a Widget for the messages as I show below:

class Message(QWidget):
    def __init__(self, title, message, parent=None):
        QWidget.__init__(self, parent)
        self.setLayout(QGridLayout())
        self.titleLabel = QLabel(title, self)
        self.titleLabel.setStyleSheet(
            "font-family: 'Roboto', sans-serif; font-size: 14px; font-weight: bold; padding: 0;")
        self.messageLabel = QLabel(message, self)
        self.messageLabel.setStyleSheet(
            "font-family: 'Roboto', sans-serif; font-size: 12px; font-weight: normal; padding: 0;")
        self.buttonClose = QPushButton(self)
        self.buttonClose.setIcon(QIcon("res/close1.png"))
        self.buttonClose.setFixedSize(14, 14)
        self.layout().addWidget(self.titleLabel, 0, 0)
        self.layout().addWidget(self.messageLabel, 1, 0)
        self.layout().addWidget(self.buttonClose, 0, 1, 2, 1)

当你想首先删除消息时,你必须使用布局的 removeWidget() 函数将它从布局中删除,然后你必须使用 deleteLater()删除自身及其子部件.当我们发送信号时,我们可以通过 sender() 获取发出它的对象,在我们的例子中它将是按钮,通过它我们获得作为我们的消息小部件的父级.然后我们使用 adjustSize() 来更新布局的正确大小.即使删除整个小部件也需要一个最小值,因此如果没有消息,建议关闭它.

When you want to remove the message first you must remove it from the layout with the removeWidget() function of the layout and then you must use deleteLater() to delete itself and its child widget. when we send a signal we can get the object that emits it through sender(), in our case it will be the button, and through this we obtain the parent that is our message widget. Then to update the correct size of the layout we use adjustSize(). Even removing the entire widget takes a minimum value so it is advisable to close it if there are no messages.

class Notification(QWidget):
    signNotifyClose = pyqtSignal(str)
    def __init__(self, parent = None):
        time = datetime.now()
        currentTime = str(time.hour) + ":" + str(time.minute) + "_"
        self.LOG_TAG = currentTime + self.__class__.__name__ + ": "
        super(QWidget, self).__init__(parent)

        self.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint)
        resolution = QDesktopWidget().screenGeometry(-1)
        screenWidth = resolution.width()
        screenHeight = resolution.height()
        print(self.LOG_TAG + "width: " + str(resolution.width()) + " height: " + str(resolution.height()))
        self.nMessages = 0
        self.mainLayout = QVBoxLayout(self)
        self.move(screenWidth, 0)

    def setNotify(self, title, message):
        m = Message(title, message, self)
        self.mainLayout.addWidget(m)
        m.buttonClose.clicked.connect(self.onClicked)
        self.nMessages += 1
        self.show()

    def onClicked(self):
        self.mainLayout.removeWidget(self.sender().parent())
        self.sender().parent().deleteLater()
        self.nMessages -= 1
        self.adjustSize()
        if self.nMessages == 0:
            self.close()

这是一个如何使用以下代码的示例:

Here is an example of how to use it with the following code:

class Example(QWidget):
    counter = 0

    def __init__(self, parent=None):
        QWidget.__init__(self, parent)
        self.setLayout(QVBoxLayout())
        btn = QPushButton("Send Notify", self)
        self.layout().addWidget(btn)

        self.notification = Notification()
        btn.clicked.connect(self.notify)


    def notify(self):
        self.counter += 1
        self.notification.setNotify("Title{}".format(self.counter),
                                    "message{}".format(self.counter))


if __name__ == '__main__':
    app = QApplication(sys.argv)
    w = Example()
    w.show()
    sys.exit(app.exec_())

这篇关于来自 QWidget 的 PyQt5 通知的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆