This commit is contained in:
Irony 2017-03-30 22:26:58 +08:00
commit c51c75ce50
13 changed files with 709 additions and 0 deletions

8
README.md Normal file
View file

@ -0,0 +1,8 @@
#各种各样的PyQt测试和例子
<br />
###[Python3.4.4 or Python3.5][PyQt5]
#1.<a href="右下角弹出框/">右下角弹出框</a><br />
#2.<a href="单实例应用/">单实例应用</a><br />

View file

@ -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)

View file

@ -0,0 +1,7 @@
#单实例应用 Application
<br />
###[Python3.4.4 or Python3.5][PyQt5]
方式一、QSharedMemory <br />
方式一、QLocalSocket, QLocalServer

View file

@ -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_())

View file

@ -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_())

View file

@ -0,0 +1,8 @@
#右下角弹出框
<br />
###[Python3.4.4 or Python3.5][PyQt5]
#截图
<img src="ScreenShot/1.png" />
<img src="ScreenShot/2.png" />

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

View file

@ -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_())

View file

@ -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_())

Binary file not shown.

Binary file not shown.

View file

@ -0,0 +1,201 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>NotifyForm</class>
<widget class="QWidget" name="NotifyForm">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>300</width>
<height>200</height>
</rect>
</property>
<property name="windowTitle">
<string>消息提示</string>
</property>
<property name="styleSheet">
<string notr="true">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: &quot;webdings&quot;;
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);
}</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout" stretch="0,1,0">
<property name="spacing">
<number>6</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QWidget" name="widgetTitle" native="true">
<property name="minimumSize">
<size>
<width>0</width>
<height>26</height>
</size>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_3">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>10</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="labelTitle">
<property name="text">
<string/>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="buttonClose">
<property name="minimumSize">
<size>
<width>26</width>
<height>26</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>26</width>
<height>26</height>
</size>
</property>
<property name="text">
<string>r</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QLabel" name="labelContent">
<property name="text">
<string/>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
<property name="margin">
<number>0</number>
</property>
</widget>
</item>
<item>
<widget class="QWidget" name="widgetBottom" native="true">
<layout class="QHBoxLayout" name="horizontalLayout">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>5</number>
</property>
<property name="rightMargin">
<number>5</number>
</property>
<property name="bottomMargin">
<number>5</number>
</property>
<item>
<spacer name="horizontalSpacer_2">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>170</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="buttonView">
<property name="minimumSize">
<size>
<width>75</width>
<height>25</height>
</size>
</property>
<property name="cursor">
<cursorShape>PointingHandCursor</cursorShape>
</property>
<property name="text">
<string>查 看</string>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>