-
-
Save edwardchanjw/3727c6b34af13a357116152df0574688 to your computer and use it in GitHub Desktop.
A PyQt "task launcher" for quick access to python scripts.
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
""" | |
A PyQt piece of black tape to cover annoying screen features. | |
terrynbrown@gmail.com, 2019-10-03 | |
""" | |
import sys | |
try: | |
from PyQt5 import QtWidgets, QtCore, Qt | |
from PyQt5.QtCore import Qt as QtConst | |
QtGui = QtWidgets | |
except ImportError: | |
from PyQt4 import QtGui, QtCore, Qt | |
from PyQt4.QtCore import Qt as QtConst | |
class Draggable(QtGui.QWidget): | |
""" | |
A draggable widget, so the window can be moved by dragging | |
its background. Thanks http://stackoverflow.com/a/7140226/1072212 | |
""" | |
def __init__(self, *args, **kwargs): | |
"""__init__""" | |
QtGui.QWidget.__init__(self, *args, **kwargs) | |
# self.setMouseTracking(True) | |
self.offset = None | |
self.msg_i = 0 | |
self.orig_size = None | |
self.setLayout(QtGui.QVBoxLayout()) | |
self.top_row = QtGui.QHBoxLayout() | |
self.layout().addLayout(self.top_row) | |
self.bot_row = QtGui.QHBoxLayout() | |
self.layout().addLayout(self.bot_row) | |
self.bot_row.addItem(QtGui.QSpacerItem(15, 5)) | |
for layout in self.bot_row, self.top_row, self.layout(): | |
layout.setSpacing(0) | |
layout.setContentsMargins(0, 0, 0, 0) | |
def mousePressEvent(self, event): | |
self.offset = event.pos() | |
def mouseMoveEvent(self, event): | |
x=event.globalX() | |
y=event.globalY() | |
x_w = self.offset.x() | |
y_w = self.offset.y() | |
self.parent().move(x-x_w, y-y_w) | |
holder = [] | |
def new_widget(): | |
main = QtGui.QMainWindow(None, | |
# QtConst.CustomizeWindowHint | | |
QtConst.WindowStaysOnTopHint | | |
QtConst.FramelessWindowHint # | | |
# QtConst.WindowCloseButtonHint | |
) | |
mainwidj = Draggable() | |
def resize(w=main): | |
w.setStyleSheet("background: black") | |
w.resize(int(sys.argv[1]), int(sys.argv[2])) | |
w.timer.stop() | |
main.timer = timer = QtCore.QTimer() | |
timer.setInterval(10000) | |
timer.timeout.connect(resize) | |
timer.start() | |
main.setCentralWidget(mainwidj) | |
main.show() | |
return main | |
def main(): | |
app = Qt.QApplication(sys.argv) | |
holder[:] = [new_widget()] | |
app.exec_() | |
if __name__ == '__main__': | |
main() |
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
""" | |
A PyQt "task launcher" for quick access to python scripts. | |
Buttons to click to make working in Windows less unproductive. | |
e.g. a button to move the current window to top or bottom half | |
of screen, because Windows-Up / Windows-Down doesn't do that. | |
Or quote the text on the clipboard properly, because Outlook | |
can't do that. | |
terrynbrown@gmail.com, 2016-12-23 | |
""" | |
import os | |
import sys | |
import time | |
try: | |
from PyQt5 import QtWidgets, QtCore, Qt | |
from PyQt5.QtCore import Qt as QtConst | |
QtGui = QtWidgets | |
except ImportError: | |
from PyQt4 import QtGui, QtCore, Qt | |
from PyQt4.QtCore import Qt as QtConst | |
COMMANDS = [] | |
MSG_FILES = ["~/.winbut_todo_int", "~/.winbut_todo_ext"] | |
ON_TIME = 300 | |
HI_TIME = 30 | |
def get_msgs(): | |
msgs = [] | |
for msg_file in MSG_FILES: | |
msg_file = os.path.expanduser(msg_file) | |
if os.path.exists(msg_file): | |
msgs.extend(open(msg_file).read().strip().split('\n')) | |
return [i for i in msgs if i.strip()] | |
class Draggable(QtGui.QWidget): | |
""" | |
A draggable widget, so the window can be moved by dragging | |
its background. Thanks http://stackoverflow.com/a/7140226/1072212 | |
""" | |
def __init__(self, *args, **kwargs): | |
"""__init__""" | |
QtGui.QWidget.__init__(self, *args, **kwargs) | |
# self.setMouseTracking(True) | |
self.offset = None | |
self.msg_i = 0 | |
self.orig_size = None | |
self.setLayout(QtGui.QVBoxLayout()) | |
self.top_row = QtGui.QHBoxLayout() | |
self.layout().addLayout(self.top_row) | |
self.bot_row = QtGui.QHBoxLayout() | |
self.layout().addLayout(self.bot_row) | |
self.bot_row.addItem(QtGui.QSpacerItem(15, 5)) | |
for layout in self.bot_row, self.top_row, self.layout(): | |
layout.setSpacing(0) | |
layout.setContentsMargins(0, 0, 0, 0) | |
def mousePressEvent(self, event): | |
self.offset = event.pos() | |
def mouseMoveEvent(self, event): | |
x=event.globalX() | |
y=event.globalY() | |
x_w = self.offset.x() | |
y_w = self.offset.y() | |
self.parent().move(x-x_w, y-y_w) | |
def command(name): | |
"""Decorator to add a button to the task bar""" | |
def makebutton(function): | |
# can't make the button yet, no Qt app. Just add to list | |
COMMANDS.append((name, function)) | |
return function | |
return makebutton | |
# now some commands to add to the bar, not part of the bar code itself | |
def place(x, y, w, h): | |
"""Wait up to 5 sec. for click on another window, then move | |
it to x, y, w, h. | |
""" | |
import win32con, win32gui, time | |
first = win32gui.GetForegroundWindow() | |
for i in range(100): | |
time.sleep(0.05) | |
hwnd = win32gui.GetForegroundWindow() | |
if hwnd != first: | |
win32gui.SetWindowPos(hwnd, win32con.HWND_TOP, x, y, w, h, 0) | |
break | |
@command("Upper") | |
def upper(): | |
# place(-1050, -330, 1050, 809) | |
place(-1050+1050, -330+330, 1050, 809) | |
@command("Lower") | |
def lower(): | |
# place(-1050, 479, 1050, 809) | |
place(-1050+1050, 479+330, 1050, 809) | |
@command("Quote") | |
def quote(): | |
"""> Quote an email message, because Outlook can't. | |
Operates on the content of the clipboard. | |
""" | |
import re | |
clipboard = Qt.QApplication.clipboard() | |
text = "> " + unicode(clipboard.text()).replace("\n", "\n> ") | |
BLANKQUOTE = re.compile("^[> ]*$") | |
out = [] | |
for line in text.split('\n'): | |
if BLANKQUOTE.match(line): | |
if out: | |
if BLANKQUOTE.match(out[-1]): | |
if len(out[-1]) > len(line): | |
out[-1] = line | |
else: | |
out.append(line) | |
else: | |
out.append(line) | |
# delete trailing blank quote lines | |
while out and BLANKQUOTE.match(out[-1]): | |
del out[-1] | |
# add trailing line | |
if out and out[-1].strip(): | |
out.append('\n') | |
text = '\n'.join(out) | |
clipboard.setText(text) | |
@command("Note") | |
def note(): | |
txt = str(QtGui.QInputDialog.getText(None, "Note", "Note")[0]) | |
timestamp = time.strftime("%Y%m%d%H%M%S") | |
with open("d:/local/quick_notes/%s.txt" % timestamp, 'w') as out: | |
out.write("%s\n\n%s\n" % (txt, time.asctime())) | |
@command("ToDo") | |
def todo(): | |
txt = str(QtGui.QInputDialog.getText(None, "To do", "To do")[0]) | |
timestamp = time.strftime("%Y%m%d%H%M%S") | |
with open(os.path.expanduser(MSG_FILES[0]), 'a') as out: | |
out.write("%s %s\n" % (txt, timestamp)) | |
# end of commands unrelated to bar code itself | |
@command("Exit") | |
def exit_(): | |
exit() | |
def show_msgs(): | |
w = holder[0].findChild(Draggable) | |
was_one = False | |
while True: | |
cull = w.top_row.takeAt(0) | |
if not cull: | |
break | |
was_one = True | |
cull.widget().deleteLater() | |
msgs = get_msgs() | |
if msgs: | |
w.msg_i = (w.msg_i+1) % len(msgs) | |
l = QtGui.QLabel(msgs[w.msg_i]) | |
l.setStyleSheet("color: white; background: red") | |
w.top_row.addWidget(l) | |
QtCore.QTimer.singleShot(HI_TIME*1000, | |
lambda: l.setStyleSheet("color: black; background: white")) | |
else: | |
if was_one: | |
w.timer.stop() | |
holder[:] = [new_widget()] | |
holder = [] | |
def new_widget(): | |
main = QtGui.QMainWindow(None, | |
# QtConst.CustomizeWindowHint | | |
QtConst.WindowStaysOnTopHint | | |
QtConst.FramelessWindowHint # | | |
# QtConst.WindowCloseButtonHint | |
) | |
mainwidj = Draggable() | |
for name, function in COMMANDS: | |
button = QtGui.QPushButton(name) | |
button.clicked.connect(function) | |
# button.setSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Minimum) | |
button.setMinimumWidth(40) | |
mainwidj.bot_row.addWidget(button) | |
mainwidj.timer = timer = QtCore.QTimer() | |
timer.setInterval(ON_TIME*1000) | |
timer.timeout.connect(show_msgs) | |
timer.start() | |
main.setCentralWidget(mainwidj) | |
main.show() | |
main.resize(min(800, 20+20*len(COMMANDS)),16) | |
x = Qt.QApplication.desktop().availableGeometry().bottomRight() | |
main.move(x - QtCore.QPoint(main.size().width(), main.size().height())) | |
return main | |
def main(): | |
app = Qt.QApplication(sys.argv) | |
holder[:] = [new_widget()] | |
app.exec_() | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment