「Desktop Mate」というデスクトップマスコットの商品が発売されました。
しかも、デフォルトのキャラクターなら無料。すごい。
さすがにこのレベルは無理だけど、昔のOfficeで見かけたイルカみたいのでいいから作りたい!
600円のパソコンでも動くデスクトップマスコットがほしい!
PythonのPyQtというライブラリを使えば、ウィンドウを透過させることができるらしいので、これを使います。
OSは、相変わらずのArch Linux + Hyprlandです。
絵は描けないので、こちらの立ち絵素材を使わせていただきます。
https://seiga.nicovideo.jp/seiga/im11005162?track=seiga_illust_keyword
現時点でのデモです。
RSSの情報とかいろいろしゃべってもらう予定。
https://www.youtube.com/watch?v=tP3c6q5fIRQ
Arch Linux(hyprland)だと、Pythonコードだけだとちゃんと透過にならないので、Hyprland.confに以下を追記しています。
windowrulev2 = float, title:^ひまり窓$
windowrulev2 = noborder, title:^ひまり窓$
windowrulev2 = noblur, title:^ひまり窓$
windowrulev2 = noshadow, title:^ひまり窓$
windowrulev2 = move 1050 480, title:^ひまり窓$
Pythonコードはこちら。
#!/home/shu/python/dtop/dtop_venv/bin/python
"""
機能:デスクトップマスコット
注意:ひまりVer
"""
import sys
import time
import random
from PyQt5.QtCore import Qt, QTimer
from PyQt5.QtGui import QPixmap
from PyQt5.QtWidgets import QApplication, QLabel, QMainWindow, QVBoxLayout, QWidget
# 定数
global HIMARI_LINES # セリフ テキストファイルから読み込む
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
global HIMARI_LINES
self.i = 1
# ウィンドウのタイトル
self.setWindowTitle('ひまり窓')
# ウィンドウを透明に設定
self.setAttribute(Qt.WA_TranslucentBackground)
self.setWindowFlags(Qt.FramelessWindowHint)
# QLabelを使って画像を表示
self.label = QLabel(self)
self.pixmap_close = QPixmap("/home/shu/picture/himari_chibi/png/chibi0.png") # 目を閉じた画像
self.pixmap_open = QPixmap("/home/shu/picture/himari_chibi/png/chibi1.png") # 目を開いた画像
self.label.setPixmap(self.pixmap_open)
self.label.setAlignment(Qt.AlignCenter)
# 位置と大きさ。Hyprlandだと位置は意味がなさそう
self.setGeometry(100, 100, 300, 300)
# セリフをテキストファイルから読み出し
with open("/home/shu/python/dtop/text/himari_lines.txt", "r", encoding="utf-8") as f:
HIMARI_LINES = [line.strip() for line in f.readlines()] # 改行を削除して読み出し
# 吹き出しのラベル
self.bubble_label = QLabel(self)
self.bubble_label.setText("")
self.bubble_label.setStyleSheet("background-color: white; border: 2px solid #000; border-radius: 10px; padding: 10px;")
self.bubble_label.setAlignment(Qt.AlignCenter)
# 吹き出しの位置と大きさを調整
self.bubble_label.setGeometry(0, 0, 300, 40)
self.bubble_label.hide() # 最初は隠す。話すときだけ表示
# 吹き出しループ
self.timer_b = QTimer(self)
self.timer_b.timeout.connect(self.update_disp_b)
self.timer_b.start(5000) # 5sec
# ひまり画像用ループ
self.timer = QTimer(self)
self.timer.timeout.connect(self.update_disp)
self.timer.start(1000) # 1000ミリ
"""
吹き出し表示用ループ
"""
def update_disp_b(self):
# ずっとしゃべってもおもしろくないのでランダムで
if random.randint(0, 2) > 1:
self.bubble_label.setText(random.choice(HIMARI_LINES))
self.bubble_label.show()
QTimer.singleShot(3000, self.reset_bubble) # 3sec後に閉じる
"""
吹き出し消去
"""
def reset_bubble(self):
# 隠す
self.bubble_label.hide()
"""
ひまり画像用ループ
"""
def update_disp(self):
# 目を開いたり閉じたりする
if random.randint(0, 2) > 1:
self.label.setPixmap(self.pixmap_close)
# 目を閉じた状態を少しだけ表示
QTimer.singleShot(100, self.reset_eye) # 100ミリ秒後に目を開ける
"""
まばたき
"""
def reset_eye(self):
# 目を開ける
self.label.setPixmap(self.pixmap_open)
"""
イベントハンドラ
"""
def resizeEvent(self, event):
self.label.setGeometry(0, 0, self.width(), self.height())
"""
main関数呼び出し
"""
if __name__ == '__main__':
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())