大阪市中央区 システムソフトウェア開発会社

営業時間:平日09:15〜18:15
MENU

ラズパイデスクトップでPyQt5入門(22) CustomWidgets in  PyQt5

著者:國松亜紗子
公開日:2020/07/02
最終更新日:2020/07/02
カテゴリー:技術情報

こんばんは。クーラーの寒さにも弱い國松です。
今回もPyQt5のtutorialを見て行きたいと思います。

参考サイト
ZetCode PyQt5 tutorial
【PythonでGUI】PyQt5 -カスタムウィジェット-

CustomWidgets in PyQt5
PyQt5のツールキットが提供するのはボタンやテキストウィジェット、スライダーなどの基本的なウィジェットだけです。
これらを組合せで自分に必要なウィジェット(CustomWidjets)作成していきます。
カスタムウィジェットは基本的に既存のウィジェットを修正したりして作成しますがゼロから自分で作成することもできます。

PyQt5 burning widget(書き込みウィジェット)
CD/DVD書き込みソフトで見る事ができるウィジェットを作成してきます。
『バーニングウィとジェットはCD\DVDの総容量と空き容量をグラフィカルに表示します』
と言われもよくわからなくても大丈夫。要するにスライダーの動きに連動して値の変化がわかるものを作成していきます。
実際にCDやDVDに書き込みが出来る訳ではないのでご注意ください。

今回作成するカスタムウィジェットはQWidgetをベースにしています。
バーニングウィジェットの配置にはQHBoxLayoutとQVBoxLayoutを使用しています。

#!/usr/bin/python3
#-*-coding: utf-8-*-

"""
In this example, we create a custom widget
"""

from PyQt5.QtWidgets import (QWidget,QSlider,QApplication,QHBoxLayout,QVBoxLayout)
from PyQt5.QtCore import QObject,Qt,pyqtSignal
from PyQt5.QtGui import QPainter,QFont,QColor,QPen
import sys

class Communicate(QObject):
   updateBW = pyqtSignal(int)

class BurningWidget(QWidget):
   def __init__(self):
      super().__init__()
      self.initUI()

   def initUI(self):
      #BurningWidgetの最小サイズを設定
      self.setMinimumSize(1,30)
      #色のつく位置を設定
      self.value = 75
      #目盛り設定
      self.num = [75,150,225,300,375,450,525,600,675]

   def setValue(self,value):
      self.value = value
   
   def paintEvent(self,e):
      qp = QPainter()
      qp.begin(self)
      self.drawWidget(qp)
      qp.end()

   def drawWidget(self,qp):
      MAX_CAPACITY = 700
      OVER_CAPACITY = 750
      
      #フォントを設定
      font = QFont('Serif',7,QFont.Light)
      qp.setFont(font)

      size = self.size()
      w = size.width()
      h = size.height()

      step = int(round(w / 10))

      #色付けされる全体の領域
      till = int(((w / OVER_CAPACITY) * self.value))
      #赤色で色付けされる領域
      full = int(((w / OVER_CAPACITY) * MAX_CAPACITY))

      if self.value >= MAX_CAPACITY:
         qp.setPen(QColor(255,255,255))
         qp.setBrush(QColor(255,255,184))
         qp.drawRect(0,0,full,h)
         qp.setPen(QColor(255,175,175))
         qp.setBrush(QColor(255,175,175))
         qp.drawRect(full,0,till-full,h)

      else:
         qp.setPen(QColor(255,255,255))
         qp.setBrush(QColor(255,255,184))
         qp.drawRect(0,0,till,h)

      pen = QPen(QColor(20,20,20),1,Qt.SolidLine)
      
      qp.setPen(pen)
      qp.setBrush(Qt.NoBrush)
      qp.drawRect(0,0,w-1,h-1)

      j = 0

      #目盛りを書く
      for i in range(step, 10*step,step):
         qp.drawLine(i,0,i,5)
         metrics = qp.fontMetrics()
         fw = metrics.width(str(self.num[j]))
         qp.drawText(i-fw/2,h/2,str(self.num[j]))
         j = j+1

class Example(QWidget):
   def __init__(self):
      super().__init__()
      self.initUI()

   def initUI(self):
      OVER_CAPACITY = 750

      sld = QSlider(Qt.Horizontal,self)
      sld.setFocusPolicy(Qt.NoFocus)
      sld.setRange(1,OVER_CAPACITY)
      sld.setValue(75)
      sld.setGeometry(30,40,150,30)
      
      self.c = Communicate()
      self.wid = BurningWidget()
      self.c.updateBW[int].connect(self.wid.setValue)

      sld.valueChanged[int].connect(self.changeValue)
      hbox = QHBoxLayout()
      hbox.addWidget(self.wid)
      vbox = QVBoxLayout()
      vbox.addStretch(1)
      vbox.addLayout(hbox)
      self.setLayout(vbox)

      self.setGeometry(300,300,390,210)
      self.setWindowTitle('Burning widget')
      self.show()

   def changeValue(self,value):
      self.c.updateBW.emit(value)
      self.wid.repaint()

if __name__ == '__main__':
   app = QApplication(sys.argv)
   ex = Example()
   sys.exit(app.exec_())

 

動画が少しぼやけてしまって申し訳ありません。今回は以上になります。それではまた。

 

    上に戻る