Last active
October 14, 2015 15:22
-
-
Save nakamuray/b28634d92908b3c11875 to your computer and use it in GitHub Desktop.
標準入力読んで画面にコメント流すやつ、 OSX でも動くかもしれない版。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'''Niconico Style Display | |
requirements: | |
PyQt5 | |
pyobjc-framework-Cocoa (pyobjc-cocoa?, osx only) | |
''' | |
import multiprocessing | |
import sys | |
import threading | |
import time | |
from PyQt5 import QtCore | |
from PyQt5 import QtGui | |
from PyQt5 import QtWidgets | |
class OutlinedLabel(QtWidgets.QLabel): | |
def paintEvent(self, *args, **kwargs): | |
# TODO: text containing newline characters | |
painter = QtGui.QPainter(self) | |
path = QtGui.QPainterPath() | |
pen = QtGui.QPen() | |
font = self.font() | |
# XXX: really? | |
y = (font.pixelSize() + self.height()) / 2 | |
pen.setWidth(1) | |
pen.setColor(QtCore.Qt.black) | |
painter.setFont(font) | |
painter.setPen(pen) | |
painter.setRenderHints( | |
QtGui.QPainter.Antialiasing | QtGui.QPainter.TextAntialiasing) | |
path.addText(0, y, font, self.text()) | |
painter.fillPath(path, QtCore.Qt.white) | |
painter.drawPath(path) | |
class Comment(QtWidgets.QMainWindow): | |
font = 'Sans Serif' | |
font_size = 24 | |
fps = 60 | |
duration = 10 | |
def __init__(self, app, message): | |
super(Comment, self).__init__() | |
self.setWindowFlags(self.windowFlags() | | |
QtCore.Qt.FramelessWindowHint | | |
QtCore.Qt.BypassWindowManagerHint | | |
QtCore.Qt.WindowStaysOnTopHint) | |
self.setAttribute(QtCore.Qt.WA_TranslucentBackground) | |
self.setFocusPolicy(QtCore.Qt.NoFocus) | |
self.app = app | |
self.label = OutlinedLabel() | |
font = QtGui.QFont(self.font, self.font_size, QtGui.QFont.Bold) | |
self.label.setFont(font) | |
palette = QtGui.QPalette() | |
palette.setColor(palette.Foreground, QtCore.Qt.white) | |
self.label.setPalette(palette) | |
self.label.setText(message) | |
self.setCentralWidget(self.label) | |
def start(self, y): | |
desktop = QtWidgets.QDesktopWidget() | |
resolution = desktop.screenGeometry() | |
self.x = resolution.width() | |
self.y = y | |
self.move(self.x, self.y) | |
self.show() | |
self.label.show() | |
self.step = (self.x + self.size().width()) / (self.duration * self.fps) | |
self.timer = QtCore.QTimer() | |
self.timer.timeout.connect(self.move_next) | |
self.timer.start(16) | |
def move_next(self): | |
self.x -= self.step | |
self.move(self.x, self.y) | |
if self.x < -self.size().width(): | |
self.timer.stop() | |
self.hide() | |
self.destroy() | |
self.app.exit() | |
def _hideMacDockIcon(): | |
if sys.platform != 'darwin': | |
return | |
import AppKit | |
info = AppKit.NSBundle.mainBundle().infoDictionary() | |
info["LSBackgroundOnly"] = "1" | |
def _main(message): | |
import random | |
_hideMacDockIcon() | |
app = QtWidgets.QApplication(sys.argv) | |
desktop = QtWidgets.QDesktopWidget() | |
resolution = desktop.screenGeometry() | |
comment = Comment(app, message) | |
comment.start(random.randint(100, resolution.height()-200)) | |
sys.exit(app.exec_()) | |
def _child_waiter(): | |
# wait for chailds (needs on osx only?) | |
while True: | |
multiprocessing.active_children() | |
time.sleep(3) | |
def main(): | |
MAX_NUM_COMMENTS = 50 | |
threading.Thread(target=_child_waiter, daemon=True).start() | |
for i, line in enumerate(sys.stdin, 1): | |
line = line.rstrip('\r\n') | |
# XXX: because moving many windows on same process is too slow on PyQt, | |
# spawn process for each windows. | |
p = multiprocessing.Process(name=i, target=_main, args=(line, )) | |
p.start() | |
active_comments = multiprocessing.active_children() | |
if len(active_comments) > MAX_NUM_COMMENTS: | |
active_comments.sort(key=lambda c: c.name) | |
active_comments[0].terminate() | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment