commit c51c75ce500195300bea2527c84db6bfa7353a3a
Author: Irony <892768447@qq.com>
Date: Thu Mar 30 22:26:58 2017 +0800
upload
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..757934f
--- /dev/null
+++ b/README.md
@@ -0,0 +1,8 @@
+#各种各样的PyQt测试和例子
+
+
+###[Python3.4.4 or Python3.5][PyQt5]
+
+#1.右下角弹出框
+
+#2.单实例应用
\ No newline at end of file
diff --git a/单实例应用/Application.py b/单实例应用/Application.py
new file mode 100644
index 0000000..5db5a1e
--- /dev/null
+++ b/单实例应用/Application.py
@@ -0,0 +1,126 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+'''
+Created on 2017年3月30日
+@author: Irony."[讽刺]
+@site: alyl.vip, orzorz.vip, irony.coding.me , irony.iask.in , mzone.iask.in
+@email: 892768447@qq.com
+@file: 单实例应用.Application
+@description:
+'''
+from PyQt5.QtCore import QSharedMemory, pyqtSignal, Qt
+from PyQt5.QtNetwork import QLocalSocket, QLocalServer
+from PyQt5.QtWidgets import QApplication
+
+
+__version__ = "0.0.1"
+
+class SharedApplication(QApplication):
+
+ def __init__(self, *args, **kwargs):
+ super(SharedApplication, self).__init__(*args, **kwargs)
+ self._running = False
+ key = "SharedApplication" + __version__
+ self._memory = QSharedMemory(key, self)
+
+ isAttached = self._memory.isAttached()
+ print("isAttached", isAttached)
+ if isAttached: # 如果进程附加在共享内存上
+ detach = self._memory.detach() # 取消进程附加在共享内存上
+ print("detach", detach)
+
+ if self._memory.create(1) and self._memory.error() != QSharedMemory.AlreadyExists:
+ # 创建共享内存,如果创建失败,则说明已经创建,否则未创建
+ print("create ok")
+ else:
+ print("create failed")
+ self._running = True
+ del self._memory
+
+ def isRunning(self):
+ return self._running
+
+class QSingleApplication(QApplication):
+
+ messageReceived = pyqtSignal(str)
+
+ def __init__(self, *args, **kwargs):
+ super(QSingleApplication, self).__init__(*args, **kwargs)
+ appid = QApplication.applicationFilePath().lower().split("/")[-1]
+ self._socketName = "qtsingleapp-" + appid
+ print("socketName", self._socketName)
+ self._activationWindow = None
+ self._activateOnMessage = False
+ self._socketServer = None
+ self._socketIn = None
+ self._socketOut = None
+ self._running = False
+
+ # 先尝试连接
+ self._socketOut = QLocalSocket(self)
+ self._socketOut.connectToServer(self._socketName)
+ self._socketOut.error.connect(self.handleError)
+ self._running = self._socketOut.waitForConnected()
+
+ if not self._running: # 程序未运行
+ self._socketOut.close()
+ del self._socketOut
+ self._socketServer = QLocalServer(self)
+ self._socketServer.listen(self._socketName)
+ self._socketServer.newConnection.connect(self._onNewConnection)
+ self.aboutToQuit.connect(self.removeServer)
+
+ def handleError(self, message):
+ print("handleError message: ", message)
+
+ def isRunning(self):
+ return self._running
+
+ def activationWindow(self):
+ return self._activationWindow
+
+ def setActivationWindow(self, activationWindow, activateOnMessage=True):
+ self._activationWindow = activationWindow
+ self._activateOnMessage = activateOnMessage
+
+ def activateWindow(self):
+ if not self._activationWindow:
+ return
+ self._activationWindow.setWindowState(
+ self._activationWindow.windowState() & ~Qt.WindowMinimized)
+ self._activationWindow.raise_()
+ self._activationWindow.activateWindow()
+
+ def sendMessage(self, message, msecs=5000):
+ if not self._socketOut:
+ return False
+ if not isinstance(message, bytes):
+ message = str(message).encode()
+ self._socketOut.write(message)
+ if not self._socketOut.waitForBytesWritten(msecs):
+ raise RuntimeError("Bytes not written within %ss" %
+ (msecs / 1000.))
+ return True
+
+ def _onNewConnection(self):
+ if self._socketIn:
+ self._socketIn.readyRead.disconnect(self._onReadyRead)
+ self._socketIn = self._socketServer.nextPendingConnection()
+ if not self._socketIn:
+ return
+ self._socketIn.readyRead.connect(self._onReadyRead)
+ if self._activateOnMessage:
+ self.activateWindow()
+
+ def _onReadyRead(self):
+ while 1:
+ message = self._socketIn.readLine()
+ if not message:
+ break
+ print("Message received: ", message)
+ self.messageReceived.emit(message.data().decode())
+
+ def removeServer(self):
+ self._socketServer.close()
+ self._socketServer.removeServer(self._socketName)
\ No newline at end of file
diff --git a/单实例应用/README.md b/单实例应用/README.md
new file mode 100644
index 0000000..e5b19f4
--- /dev/null
+++ b/单实例应用/README.md
@@ -0,0 +1,7 @@
+#单实例应用 Application
+
+
+###[Python3.4.4 or Python3.5][PyQt5]
+
+方式一、QSharedMemory
+方式一、QLocalSocket, QLocalServer
\ No newline at end of file
diff --git a/单实例应用/TestQSharedMemory.py b/单实例应用/TestQSharedMemory.py
new file mode 100644
index 0000000..ff0dc14
--- /dev/null
+++ b/单实例应用/TestQSharedMemory.py
@@ -0,0 +1,33 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+'''
+Created on 2017年3月30日
+@author: Irony."[讽刺]
+@site: alyl.vip, orzorz.vip, irony.coding.me , irony.iask.in , mzone.iask.in
+@email: 892768447@qq.com
+@file: TestQSharedMemory
+@description:
+'''
+from PyQt5.QtWidgets import QWidget
+
+
+from Application import SharedApplication # @UnresolvedImport
+
+__version__ = "0.0.1"
+
+class Widget(QWidget):
+
+ def __init__(self,*args,**kwargs):
+ super(Widget, self).__init__(*args,**kwargs)
+
+if __name__ == "__main__":
+ import sys,os
+ print(os.getpid())
+ app = SharedApplication(sys.argv)
+ if app.isRunning():
+ print("app have already running")
+ sys.exit(0)
+ w = Widget()
+ w.show()
+ sys.exit(app.exec_())
\ No newline at end of file
diff --git a/单实例应用/TestQSingleApplication.py b/单实例应用/TestQSingleApplication.py
new file mode 100644
index 0000000..992827b
--- /dev/null
+++ b/单实例应用/TestQSingleApplication.py
@@ -0,0 +1,34 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+'''
+Created on 2017年3月30日
+@author: Irony."[讽刺]
+@site: alyl.vip, orzorz.vip, irony.coding.me , irony.iask.in , mzone.iask.in
+@email: 892768447@qq.com
+@file: TestQSingleApplication
+@description:
+'''
+from PyQt5.QtWidgets import QTextEdit
+
+from Application import QSingleApplication # @UnresolvedImport
+
+
+__version__ = "0.0.1"
+
+class Widget(QTextEdit):
+
+ def __init__(self, *args, **kwargs):
+ super(Widget, self).__init__(*args, **kwargs)
+
+if __name__ == "__main__":
+ import sys
+ app = QSingleApplication(sys.argv)
+ if app.isRunning():
+ app.sendMessage("app is running")
+ sys.exit(0)
+ t = Widget()
+ app.setActivationWindow(t)
+ app.messageReceived.connect(t.append)
+ t.show()
+ sys.exit(app.exec_())
diff --git a/右下角弹出框/README.md b/右下角弹出框/README.md
new file mode 100644
index 0000000..40220c2
--- /dev/null
+++ b/右下角弹出框/README.md
@@ -0,0 +1,8 @@
+#右下角弹出框
+
+
+###[Python3.4.4 or Python3.5][PyQt5]
+
+#截图
+
+
\ No newline at end of file
diff --git a/右下角弹出框/ScreenShot/1.png b/右下角弹出框/ScreenShot/1.png
new file mode 100644
index 0000000..5867c95
Binary files /dev/null and b/右下角弹出框/ScreenShot/1.png differ
diff --git a/右下角弹出框/ScreenShot/2.png b/右下角弹出框/ScreenShot/2.png
new file mode 100644
index 0000000..5fefe0d
Binary files /dev/null and b/右下角弹出框/ScreenShot/2.png differ
diff --git a/右下角弹出框/UiNotify.py b/右下角弹出框/UiNotify.py
new file mode 100644
index 0000000..20d26aa
--- /dev/null
+++ b/右下角弹出框/UiNotify.py
@@ -0,0 +1,111 @@
+# -*- coding: utf-8 -*-
+
+# Form implementation generated from reading ui file 'notify.ui'
+#
+# Created by: PyQt5 UI code generator 5.8
+#
+# WARNING! All changes made in this file will be lost!
+
+from PyQt5 import QtCore, QtGui, QtWidgets
+
+class Ui_NotifyForm(object):
+ def setupUi(self, NotifyForm):
+ NotifyForm.setObjectName("NotifyForm")
+ NotifyForm.resize(300, 200)
+ NotifyForm.setStyleSheet("QWidget#widgetTitle {\n"
+" background-color: rgb(76, 169, 106);\n"
+"}\n"
+"QWidget#widgetBottom {\n"
+" border-top-style: solid;\n"
+" border-top-width: 2px;\n"
+" border-top-color: rgb(185, 218, 201);\n"
+"}\n"
+"QLabel#labelTitle {\n"
+" color: rgb(255, 255, 255);\n"
+"}\n"
+"QLabel#labelContent {\n"
+" padding: 5px;\n"
+"}\n"
+"QPushButton {\n"
+" border: none;\n"
+" background: transparent;\n"
+"}\n"
+"QPushButton#buttonClose {\n"
+" font-family: \"webdings\";\n"
+" color: rgb(255, 255, 255);\n"
+"}\n"
+"QPushButton#buttonClose:hover {\n"
+" background-color: rgb(212, 64, 39);\n"
+"}\n"
+"QPushButton#buttonView {\n"
+" color: rgb(255, 255, 255);\n"
+" border-radius: 5px;\n"
+" border: solid 1px rgb(76, 169, 106);\n"
+" background-color: rgb(76, 169, 106);\n"
+"}\n"
+"QPushButton#buttonView:hover {\n"
+" color: rgb(0, 0, 0);\n"
+"}")
+ self.verticalLayout = QtWidgets.QVBoxLayout(NotifyForm)
+ self.verticalLayout.setContentsMargins(0, 0, 0, 0)
+ self.verticalLayout.setSpacing(6)
+ self.verticalLayout.setObjectName("verticalLayout")
+ self.widgetTitle = QtWidgets.QWidget(NotifyForm)
+ self.widgetTitle.setMinimumSize(QtCore.QSize(0, 26))
+ self.widgetTitle.setObjectName("widgetTitle")
+ self.horizontalLayout_3 = QtWidgets.QHBoxLayout(self.widgetTitle)
+ self.horizontalLayout_3.setContentsMargins(10, 0, 0, 0)
+ self.horizontalLayout_3.setSpacing(0)
+ self.horizontalLayout_3.setObjectName("horizontalLayout_3")
+ self.labelTitle = QtWidgets.QLabel(self.widgetTitle)
+ self.labelTitle.setText("")
+ self.labelTitle.setObjectName("labelTitle")
+ self.horizontalLayout_3.addWidget(self.labelTitle)
+ spacerItem = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
+ self.horizontalLayout_3.addItem(spacerItem)
+ self.buttonClose = QtWidgets.QPushButton(self.widgetTitle)
+ self.buttonClose.setMinimumSize(QtCore.QSize(26, 26))
+ self.buttonClose.setMaximumSize(QtCore.QSize(26, 26))
+ self.buttonClose.setObjectName("buttonClose")
+ self.horizontalLayout_3.addWidget(self.buttonClose)
+ self.verticalLayout.addWidget(self.widgetTitle)
+ self.labelContent = QtWidgets.QLabel(NotifyForm)
+ self.labelContent.setText("")
+ self.labelContent.setWordWrap(True)
+ self.labelContent.setObjectName("labelContent")
+ self.verticalLayout.addWidget(self.labelContent)
+ self.widgetBottom = QtWidgets.QWidget(NotifyForm)
+ self.widgetBottom.setObjectName("widgetBottom")
+ self.horizontalLayout = QtWidgets.QHBoxLayout(self.widgetBottom)
+ self.horizontalLayout.setContentsMargins(0, 5, 5, 5)
+ self.horizontalLayout.setSpacing(0)
+ self.horizontalLayout.setObjectName("horizontalLayout")
+ spacerItem1 = QtWidgets.QSpacerItem(170, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
+ self.horizontalLayout.addItem(spacerItem1)
+ self.buttonView = QtWidgets.QPushButton(self.widgetBottom)
+ self.buttonView.setMinimumSize(QtCore.QSize(75, 25))
+ self.buttonView.setCursor(QtGui.QCursor(QtCore.Qt.PointingHandCursor))
+ self.buttonView.setObjectName("buttonView")
+ self.horizontalLayout.addWidget(self.buttonView)
+ self.verticalLayout.addWidget(self.widgetBottom)
+ self.verticalLayout.setStretch(1, 1)
+
+ self.retranslateUi(NotifyForm)
+ QtCore.QMetaObject.connectSlotsByName(NotifyForm)
+
+ def retranslateUi(self, NotifyForm):
+ _translate = QtCore.QCoreApplication.translate
+ NotifyForm.setWindowTitle(_translate("NotifyForm", "消息提示"))
+ self.buttonClose.setText(_translate("NotifyForm", "r"))
+ self.buttonView.setText(_translate("NotifyForm", "查 看"))
+
+
+if __name__ == "__main__":
+ import sys
+ app = QtWidgets.QApplication(sys.argv)
+ NotifyForm = QtWidgets.QWidget()
+ ui = Ui_NotifyForm()
+ ui.setupUi(NotifyForm)
+ NotifyForm.show()
+ sys.exit(app.exec_())
+
diff --git a/右下角弹出框/WindowNotify.py b/右下角弹出框/WindowNotify.py
new file mode 100644
index 0000000..eecff02
--- /dev/null
+++ b/右下角弹出框/WindowNotify.py
@@ -0,0 +1,181 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+'''
+Created on 2017年3月30日
+@author: Irony."[讽刺]
+@site: alyl.vip, orzorz.vip, irony.coding.me , irony.iask.in , mzone.iask.in
+@email: 892768447@qq.com
+@file: WindowNotify
+@description:
+'''
+import webbrowser
+
+from PyQt5.QtCore import Qt, QPropertyAnimation, QPoint, QTimer, pyqtSignal
+from PyQt5.QtWidgets import QWidget, QPushButton
+
+from UiNotify import Ui_NotifyForm # @UnresolvedImport
+
+
+__version__ = "0.0.1"
+
+
+class WindowNotify(QWidget, Ui_NotifyForm):
+
+ SignalClosed = pyqtSignal() # 弹窗关闭信号
+
+ def __init__(self, title="", content="", timeout=5000, *args, **kwargs):
+ super(WindowNotify, self).__init__(*args, **kwargs)
+ self.setupUi(self)
+ self.setTitle(title).setContent(content)
+ self._timeout = timeout
+ self._init()
+
+ def setTitle(self, title):
+ if title:
+ self.labelTitle.setText(title)
+ return self
+
+ def title(self):
+ return self.labelTitle.text()
+
+ def setContent(self, content):
+ if content:
+ self.labelContent.setText(content)
+ return self
+
+ def content(self):
+ return self.labelContent.text()
+
+ def setTimeout(self, timeout):
+ if isinstance(timeout, int):
+ self._timeout = timeout
+ return self
+
+ def timeout(self):
+ return self._timeout
+
+ def onView(self):
+ print("onView")
+ webbrowser.open_new_tab("http://alyl.vip")
+
+ def onClose(self):
+ #点击关闭按钮时
+ print("onClose")
+ self.isShow = False
+ QTimer.singleShot(100, self.closeAnimation)#启动弹回动画
+
+ def _init(self):
+ # 隐藏任务栏|去掉边框|顶层显示
+ self.setWindowFlags(Qt.Tool | Qt.X11BypassWindowManagerHint |
+ Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint)
+ # 关闭按钮事件
+ self.buttonClose.clicked.connect(self.onClose)
+ # 点击查看按钮
+ self.buttonView.clicked.connect(self.onView)
+ # 是否在显示标志
+ self.isShow = True
+ # 超时
+ self._timeouted = False
+ # 桌面
+ self._desktop = QApplication.instance().desktop()
+ # 窗口初始开始位置
+ self._startPos = QPoint(
+ self._desktop.screenGeometry().width() - self.width() - 5,
+ self._desktop.screenGeometry().height()
+ )
+ # 窗口弹出结束位置
+ self._endPos = QPoint(
+ self._desktop.screenGeometry().width() - self.width() - 5,
+ self._desktop.availableGeometry().height() - self.height() - 5
+ )
+ # 初始化位置到右下角
+ self.move(self._startPos)
+
+ # 动画
+ self.animation = QPropertyAnimation(self, b"pos")
+ self.animation.finished.connect(self.onAnimationEnd)
+ self.animation.setDuration(1000) # 1s
+
+ # 弹回定时器
+ self._timer = QTimer(self, timeout=self.closeAnimation)
+
+ def show(self, title="", content="", timeout=5000):
+ self._timer.stop() # 停止定时器,防止第二个弹出窗弹出时之前的定时器出问题
+ self.hide() # 先隐藏
+ self.move(self._startPos) # 初始化位置到右下角
+ super(WindowNotify, self).show()
+ self.setTitle(title).setContent(content).setTimeout(timeout)
+ return self
+
+ def showAnimation(self):
+ print("showAnimation isShow = True")
+ # 显示动画
+ self.isShow = True
+ self.animation.stop()#先停止之前的动画,重新开始
+ self.animation.setStartValue(self.pos())
+ self.animation.setEndValue(self._endPos)
+ self.animation.start()
+ # 弹出5秒后,如果没有焦点则弹回去
+ self._timer.start(self._timeout)
+# QTimer.singleShot(self._timeout, self.closeAnimation)
+
+ def closeAnimation(self):
+ print("closeAnimation hasFocus", self.hasFocus())
+ # 关闭动画
+ if self.hasFocus():
+ # 如果弹出后倒计时5秒后还有焦点存在则失去焦点后需要主动触发关闭
+ self._timeouted = True
+ return # 如果有焦点则不关闭
+ self.isShow = False
+ self.animation.stop()
+ self.animation.setStartValue(self.pos())
+ self.animation.setEndValue(self._startPos)
+ self.animation.start()
+
+ def onAnimationEnd(self):
+ # 动画结束
+ print("onAnimationEnd isShow", self.isShow)
+ if not self.isShow:
+ print("onAnimationEnd close()")
+ self.close()
+ print("onAnimationEnd stop timer")
+ self._timer.stop()
+ print("onAnimationEnd close and emit signal")
+ self.SignalClosed.emit()
+
+ def enterEvent(self, event):
+ super(WindowNotify, self).enterEvent(event)
+ # 设置焦点(好像没啥用,不过鼠标点击一下后,该方法就有用了)
+ print("enterEvent setFocus Qt.MouseFocusReason")
+ self.setFocus(Qt.MouseFocusReason)
+
+ def leaveEvent(self, event):
+ super(WindowNotify, self).leaveEvent(event)
+ # 取消焦点
+ print("leaveEvent clearFocus")
+ self.clearFocus()
+ if self._timeouted:
+ QTimer.singleShot(1000, self.closeAnimation)
+
+if __name__ == "__main__":
+ import sys
+ from PyQt5.QtWidgets import QApplication, QHBoxLayout
+ app = QApplication(sys.argv)
+
+ window = QWidget()
+ notify = WindowNotify(parent=window)
+
+ layout = QHBoxLayout(window)
+
+ b1 = QPushButton(
+ "弹窗1", window, clicked=lambda: notify.show(content=b1.text()).showAnimation())
+ b2 = QPushButton(
+ "弹窗2", window, clicked=lambda: notify.show(content=b2.text()).showAnimation())
+
+ layout.addWidget(b1)
+ layout.addWidget(b2)
+
+ window.show()
+
+ sys.exit(app.exec_())
diff --git a/右下角弹出框/__pycache__/UiNotify.cpython-34.pyc b/右下角弹出框/__pycache__/UiNotify.cpython-34.pyc
new file mode 100644
index 0000000..04c1504
Binary files /dev/null and b/右下角弹出框/__pycache__/UiNotify.cpython-34.pyc differ
diff --git a/右下角弹出框/__pycache__/UiNotify.cpython-35.pyc b/右下角弹出框/__pycache__/UiNotify.cpython-35.pyc
new file mode 100644
index 0000000..84e0a4a
Binary files /dev/null and b/右下角弹出框/__pycache__/UiNotify.cpython-35.pyc differ
diff --git a/右下角弹出框/notify.ui b/右下角弹出框/notify.ui
new file mode 100644
index 0000000..f5ceae3
--- /dev/null
+++ b/右下角弹出框/notify.ui
@@ -0,0 +1,201 @@
+
+
+ NotifyForm
+
+
+
+ 0
+ 0
+ 300
+ 200
+
+
+
+ 消息提示
+
+
+ QWidget#widgetTitle {
+ background-color: rgb(76, 169, 106);
+}
+QWidget#widgetBottom {
+ border-top-style: solid;
+ border-top-width: 2px;
+ border-top-color: rgb(185, 218, 201);
+}
+QLabel#labelTitle {
+ color: rgb(255, 255, 255);
+}
+QLabel#labelContent {
+ padding: 5px;
+}
+QPushButton {
+ border: none;
+ background: transparent;
+}
+QPushButton#buttonClose {
+ font-family: "webdings";
+ color: rgb(255, 255, 255);
+}
+QPushButton#buttonClose:hover {
+ background-color: rgb(212, 64, 39);
+}
+QPushButton#buttonView {
+ color: rgb(255, 255, 255);
+ border-radius: 5px;
+ border: solid 1px rgb(76, 169, 106);
+ background-color: rgb(76, 169, 106);
+}
+QPushButton#buttonView:hover {
+ color: rgb(0, 0, 0);
+}
+
+
+
+ 6
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+ -
+
+
+
+ 0
+ 26
+
+
+
+
+ 0
+
+
+ 10
+
+
+ 0
+
+
+ 0
+
+
+ 0
+
+
-
+
+
+
+
+
+
+ -
+
+
+ Qt::Horizontal
+
+
+
+ 40
+ 20
+
+
+
+
+ -
+
+
+
+ 26
+ 26
+
+
+
+
+ 26
+ 26
+
+
+
+ r
+
+
+
+
+
+
+ -
+
+
+
+
+
+ true
+
+
+ 0
+
+
+
+ -
+
+
+
+ 0
+
+
+ 0
+
+
+ 5
+
+
+ 5
+
+
+ 5
+
+
-
+
+
+ Qt::Horizontal
+
+
+
+ 170
+ 20
+
+
+
+
+ -
+
+
+
+ 75
+ 25
+
+
+
+ PointingHandCursor
+
+
+ 查 看
+
+
+
+
+
+
+
+
+
+
+