サムネにマウスカーソルを重ねると、再生ボタンがオーバーレイされて、クリックすると再生できる!っという仕組って結構見ますよね!
これを、PySideでやる方法をご紹介したいと思います!(`・ω・´)ゞ
リソース
カスタムウィジェットの作成にあたり、サムネは「160 x 90」の画像、オーバーレイする再生ボタンを「64 x 64」の画像で用意しました!
サムネ | 再生ボタン |
---|---|
オーバーレイする再生ボタンは、半透明もOKです(*´ω`*)b
クラスの骨格
「QLabel」を継承してクラスを作っていきます!サムネをクリックした時のシグナル、オーバーレイする画像の設定をクラス変数で定義します。
from PySide import QtCore, QtGui class PlaybackLabel(QtGui.QLabel): iconClicked = QtCore.Signal() overlayIcon = QtGui.QPixmap(r'D:/playIcon.png')
__init__の定義
「__init__」では、サムネのファイルパスと、親のWidgetを指定できるようにします。合わせて、マウスカーソルがHover状態であるか管理するためのインスタンス変数を用意し、自身にQPixmapを設定してサムネを表示できるようにします。
from PySide import QtCore, QtGui class PlaybackLabel(QtGui.QLabel): iconClicked = QtCore.Signal() overlayIcon = QtGui.QPixmap(r'D:/playIcon.png') def __init__(self, filename=None, parent=None): super(PlaybackLabel, self).__init__(parent) self.__isHover = False self.setPixmap(QtGui.QPixmap(filename))
Hover状態の管理
マウスカーソルがWidgetに重なった状態を検知するために、「enterEvent」と「leaveEvent」をオーバーライドしていきます。「enterEvent」はマウスカーソルが重なった時、「leaveEvent」はマウスカーソルが抜け出した時に実行されるイベントです(`・ω・´)ゞ
from PySide import QtCore, QtGui class PlaybackLabel(QtGui.QLabel): iconClicked = QtCore.Signal() overlayIcon = QtGui.QPixmap(r'D:/playIcon.png') def __init__(self, filename=None, parent=None): super(PlaybackLabel, self).__init__(parent) self.__isHover = False self.setPixmap(QtGui.QPixmap(filename)) def enterEvent(self, event): super(PlaybackLabel, self).enterEvent(event) self.__isHover = True self.repaint()# 描画の更新 def leaveEvent(self, event): super(PlaybackLabel, self).leaveEvent(event) self.__isHover = False self.repaint()# 描画の更新
シグナルのエミット
サムネがクリックされた時にシグナルがエミットするように、「mousePressEvent」をオーバーライドします。
from PySide import QtCore, QtGui class PlaybackLabel(QtGui.QLabel): iconClicked = QtCore.Signal() overlayIcon = QtGui.QPixmap(r'D:/playIcon.png') def __init__(self, filename=None, parent=None): super(PlaybackLabel, self).__init__(parent) self.__isHover = False self.setPixmap(QtGui.QPixmap(filename)) def enterEvent(self, event): super(PlaybackLabel, self).enterEvent(event) self.__isHover = True self.repaint() def leaveEvent(self, event): super(PlaybackLabel, self).leaveEvent(event) self.__isHover = False self.repaint() def mousePressEvent(self, event): super(PlaybackLabel, self).mousePressEvent(event) self.iconClicked.emit()
描画処理
インスタンス変数で管理しているHover状態の時だけ、アイコンを追加で描画するようにしていきます!
from PySide import QtCore, QtGui class PlaybackLabel(QtGui.QLabel): iconClicked = QtCore.Signal() overlayIcon = QtGui.QPixmap(r'D:/playIcon.png') def __init__(self, filename=None, parent=None): super(PlaybackLabel, self).__init__(parent) self.__isHover = False self.setPixmap(QtGui.QPixmap(filename)) def enterEvent(self, event): super(PlaybackLabel, self).enterEvent(event) self.__isHover = True self.repaint() def leaveEvent(self, event): super(PlaybackLabel, self).leaveEvent(event) self.__isHover = False self.repaint() def mousePressEvent(self, event): super(PlaybackLabel, self).mousePressEvent(event) self.iconClicked.emit() def paintEvent(self, event): super(PlaybackLabel, self).paintEvent(event) # Hover状態の時の処理 if self.__isHover: painter = QtGui.QPainter() painter.begin(self) painter.setRenderHint(QtGui.QPainter.Antialiasing) # サムネの中心と、再生ボタンの中心の差分を求めて、描画位置を決める painter.translate( (painter.device().width()/2) - (self.overlayIcon.width()/2), (painter.device().height()/2) - (self.overlayIcon.height()/2) ) # 再生ボタンを描画する painter.drawPixmap(QtCore.QPoint(0, 0), self.overlayIcon) painter.end()
実験
以下のコードで実験してみます!(*´ω`*)b
window = QtGui.QWidget() window.setWindowFlags(QtCore.Qt.Window) layout = QtGui.QHBoxLayout(window) thumbnail = PlaybackLabel(r'D:\thumbnail.png') #thumbnail.iconClicked.connect(some_action) layout.addWidget(thumbnail) window.show()
マウスカーソルが重なったときだけ、再生ボタンが重なるようになりました!あとはクリックした時の処理を、シグナルにコネクションしてください!(`・ω・´)ゞ
他にも、閉じるボタンにしたりすれば用途も広がると思います!