PyQt5
ウィンドウの背景を透明に設定し、常に最前面に表示し、透明で、枠なしにする#
self.setAttribute(Qt.WA_TranslucentBackground) # ウィンドウの背景を透明にする
self.setWindowFlags(Qt.WindowStaysOnTopHint | Qt.FramelessWindowHint | Qt.Tool) # ウィンドウを最前面に表示し、枠なしで、タスクバーにアイコンを表示しない
枠がなくなったのでマウスでドラッグできなくなり、マウスイベントを再実装してウィジェットをドラッグする:
# マウスをドラッグできるように移動イベントを再実装
def mouseMoveEvent(self, e: QMouseEvent):
if self._tracking:
self._endPos = e.pos() - self._startPos
self.move(self.pos() + self._endPos)
def mousePressEvent(self, e: QMouseEvent):
if e.button() == Qt.LeftButton:
self._startPos = QPoint(e.x(), e.y())
self._tracking = True
def mouseReleaseEvent(self, e: QMouseEvent):
if e.button() == Qt.LeftButton:
self._tracking = False
self._startPos = None
self._endPos = None
完全なコード:
# -*- coding: utf-8 -*-
import PyQt5
import sys
import cv2
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from UI import Ui_MainWindow
class MyWindow(QMainWindow, Ui_MainWindow):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.setupUi(self)
self.setAttribute(Qt.WA_TranslucentBackground) # ウィンドウの背景を透明にする
self.setWindowFlags(Qt.WindowStaysOnTopHint | Qt.FramelessWindowHint | Qt.Tool) # ウィンドウを最前面に表示し、枠なしで、タスクバーにアイコンを表示しない
def mouseMoveEvent(self, e: QMouseEvent): # 移動イベントを再実装
if self._tracking:
self._endPos = e.pos() - self._startPos
self.move(self.pos() + self._endPos)
def mousePressEvent(self, e: QMouseEvent):
if e.button() == Qt.LeftButton:
self._startPos = QPoint(e.x(), e.y())
self._tracking = True
def mouseReleaseEvent(self, e: QMouseEvent):
if e.button() == Qt.LeftButton:
self._tracking = False
self._startPos = None
self._endPos = None
if __name__ == "__main__":
app = QApplication(sys.argv)
mainWindow = MyWindow()
mainWindow.show()
sys.exit(app.exec_())
PyQt5 を使用してウィンドウの小さなウィジェットを描画する#
コードは以下の通りです:
# -*- coding:utf-8 -*-
# pyqt5を利用して針時計を表示し、実施時間を示す
# こういった機能を実現したいと思い、pyqt5には現成のコンポーネントがないため、描画の方法で実現するしかないと考えました。
# 描画と言えば、turtleフレームワークが最も一般的な選択ですが、実際にはpyqt5のQPainterコンポーネントでも実現可能です。そして、最終的に表示される
# 効果は非常に美しいです。
# 実現の考え方:pyqt5のQPainterコンポーネントを使用して時計のグラフを描画し、最後にタイマーを使って現在の時間の表示位置を変更し続けます。
# こうして最終的に針時計が動き続けるプロセスを実現しました。
# 前のUIアプリケーションと同様に、使用するUI関連のコンポーネントライブラリはこの3つです。
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
# 今回は数学計算ライブラリを新たに使用しました。データ計算に関連する部分があるためです。
from math import *
# アプリケーション操作関連のモジュール
import sys
class PointerClock(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle("動的針時計")
self.timer = QTimer()
self.setAttribute(Qt.WA_TranslucentBackground) # ウィンドウの背景を透明にする
self.setWindowFlags(Qt.WindowStaysOnTopHint | Qt.FramelessWindowHint | Qt.Tool) # ウィンドウを最前面に表示し、枠なしで、タスクバーにアイコンを表示しない
# ウィンドウのタイマーを設定
self.timer.timeout.connect(self.update)
self.timer.start(1000)
# マウスをドラッグできるように移動イベントを再実装
def mouseMoveEvent(self, e: QMouseEvent):
if self._tracking:
self._endPos = e.pos() - self._startPos
self.move(self.pos() + self._endPos)
def mousePressEvent(self, e: QMouseEvent):
if e.button() == Qt.LeftButton:
self._startPos = QPoint(e.x(), e.y())
self._tracking = True
def mouseReleaseEvent(self, e: QMouseEvent):
if e.button() == Qt.LeftButton:
self._tracking = False
self._startPos = None
self._endPos = None
def paintEvent(self, event):
'''
リアルタイムで針の画像を更新
:param event:
:return:
'''
'''それぞれの時、分、秒の座標点を定義'''
'''
QPoint(int x, int y);座標点を作成し、x、yはそれぞれ横座標、縦座標を表します
'''
hour_point = [QPoint(7, 8), QPoint(-7, 8), QPoint(0, -30)]
min_point = [QPoint(7, 8), QPoint(-7, 8), QPoint(0, -65)]
secn_point = [QPoint(7, 8), QPoint(-7, 8), QPoint(0, -80)]
'''3種類の色を定義し、後で3種類の針の色を設定します'''
hour_color = QColor(182, 98, 0, 182)
min_color = QColor(0, 130, 130, 155)
sec_color = QColor(0, 155, 227, 155)
'''QWidgetオブジェクトの幅と高さの最小値を取得'''
min_size = min(self.width(), self.height())
painter = QPainter(self) # 座標系の画像描画オブジェクトを作成
painter.setRenderHint(QPainter.Antialiasing)
# QWidgetオブジェクトの中心位置を描画の中心座標点として設定
painter.translate(self.width() / 2, self.height() / 2)
# サイズをスケーリング
painter.scale(int(min_size / 200), int(min_size / 200))
# 状態を保存
painter.save()
'''時計の文字盤の時間目盛り線を描画'''
for a in range(0, 60):
if (a % 5) != 0:
# 1/60ごとに目盛り線を描画し、分の目盛り線とする
painter.setPen(min_color)
painter.drawLine(92, 0, 96, 0)
else:
# 5/60ごとに目盛り線を描画し、時の目盛り線とする
painter.setPen(hour_color)
painter.drawLine(88, 0, 96, 0) # 時の目盛り線を描画
# 毎分6度回転
painter.rotate(360 / 60)
# 状態を復元
painter.restore()
'''時計の文字盤の数字を描画'''
# 状態を保存
painter.save()
# フォントオブジェクトを取得
font = painter.font()
# 太字に設定
font.setBold(True)
painter.setFont(font)
# フォントサイズを取得
font_size = font.pointSize()
# 以前に定義した色を設定
painter.setPen(hour_color)
hour_num = 0
radius = 100
for i in range(0, 12):
# 12時間制に従い、3時間ごとに1つの時間の数字を描画し、4回繰り返す必要があります
hour_num = i + 3 # QT-Qpainterの座標系に基づいて、3時間の目盛り線は座標軸の0度に対応
if hour_num > 12:
hour_num = hour_num - 12
# フォントのサイズに基づいて、時間の数字を書くx、yの位置を計算
x = radius * 0.8 * cos(i * 30 * pi / 180.0) - font_size
y = radius * 0.8 * sin(i * 30 * pi / 180.0) - font_size / 2.0
width = font_size * 2
height = font_size
painter.drawText(QRectF(x, y, width, height), Qt.AlignCenter, str(hour_num))
# 状態を復元
painter.restore()
'''時計の文字盤の時、分、秒の針を描画'''
# 現在の時間を取得
time = QTime.currentTime()
# 時針を描画
painter.save()
# アウトラインをキャンセル
painter.setPen(Qt.NoPen)
# 時針の色を設定
painter.setBrush(hour_color)
# 時針を反時計回りに回転
painter.rotate(30 * (time.hour() + time.minute() / 60))
# 時計の針を描画
painter.drawConvexPolygon(QPolygonF(hour_point))
# 状態を復元
painter.restore()
# 分針を描画
painter.save()
# アウトラインをキャンセル
painter.setPen(Qt.NoPen)
# 分針の色を設定
painter.setBrush(min_color)
# 分針を反時計回りに回転
painter.rotate(6 * (time.minute() + time.second() / 60))
# 分針を描画
painter.drawConvexPolygon(QPolygonF(min_point))
# 状態を復元
painter.restore()
# 秒針を描画
painter.save()
# アウトラインをキャンセル
painter.setPen(Qt.NoPen)
# 秒針の色を設定
painter.setBrush(sec_color)
# 秒針を反時計回りに回転
painter.rotate(6 * time.second())
# 秒針を描画
painter.drawConvexPolygon(QPolygonF(secn_point))
# 状態を復元
painter.restore()
if __name__ == "__main__":
app = QApplication(sys.argv)
form = PointerClock()
form.show()
app.exec_()