2024-08-17

ラジオボタンの機能をプッシュボタンで実現する

PySide (Qt for Python) は、Qt(キュート)の Python バインディングで、GUI などを構築するためのクロスプラットフォームなライブラリです。Linux/X11, macOS および Microsoft Windows をサポートしています。配布ライセンスは LGPL で公開されています。

ラジオボタンの機能とは、複数のラジオボタンを並べて、その中から一つのみが選ばれる機能を指しています。この、「ひとつのみが選ばれる機能」を、プッシュボタンで実現する例を紹介します。

下記の OS 環境で動作確認をしています。

RHEL 9.4 x86_64
Python 3.12.1
PySide6 6.7.2

ここで紹介するサンプルでは、みふねたかし氏のサイト [1] で紹介されているイラストを、サイズを変更して利用させていただいています(下記)。

QRadioButton を利用した場合

まずはラジオボタンを3つ、横に並べたサンプルを示します。

qt_radiobutton_fruit_1.py
import sys
from PySide6.QtGui import QIcon
from PySide6.QtWidgets import (
QApplication,
QButtonGroup,
QHBoxLayout,
QRadioButton,
QWidget,
)
class Example(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle('果物選択')
hbox = QHBoxLayout()
self.setLayout(hbox)
rb_apple = QRadioButton('林檎')
rb_apple.setIcon(QIcon('fruit_apple.png'))
hbox.addWidget(rb_apple)
rb_apple.toggle()
rb_grape = QRadioButton('葡萄')
rb_grape.setIcon(QIcon('fruit_grape.png'))
hbox.addWidget(rb_grape)
rb_orange = QRadioButton('蜜柑')
rb_orange.setIcon(QIcon('fruit_orange.png'))
hbox.addWidget(rb_orange)
self.but_group = but_group = QButtonGroup()
but_group.addButton(rb_apple)
but_group.addButton(rb_grape)
but_group.addButton(rb_orange)
but_group.buttonToggled.connect(self.selection_changed)
def selection_changed(self, button, state):
if state:
status = 'オン'
else:
status = 'オフ'
print('「%s」を%sにしました。' % (button.text(), status))
def main():
app = QApplication(sys.argv)
ex = Example()
ex.show()
sys.exit(app.exec())
if __name__ == '__main__':
main()
qt_radiobutton_fruit_1.py の実行例
qt_radiobutton_fruit_1.py の実行時の出力例
「林檎」をオフにしました。
「葡萄」をオンにしました。
「葡萄」をオフにしました。
「蜜柑」をオンにしました。
「蜜柑」をオフにしました。
「林檎」をオンにしました。

もし、レイアウト上の問題や、あるいは好みの問題から、ラジオボタンのチェック部分を取り除き、文字列はツールチップをポップアップして表示させるようにして、イメージだけのボタンにしたい場合、QRadioButton では実現できません。

QPushButton を利用した場合

QRadioButton が継承している QAbstractButton クラスは、QPushButton も継承していて、QRadioButton の「ひとつのみが選ばれる機能」という排他的な選択機能も実装しています。

そこで、QPushButton を利用して、ラジオボタンの「ひとつのみが選ばれる機能」という排他的な選択機能を実現しました。

サンプルを下記に示しました。

qt_radiobutton_fruit_2.py
import sys
from PySide6.QtCore import QSize
from PySide6.QtGui import QIcon
from PySide6.QtWidgets import (
QApplication,
QButtonGroup,
QHBoxLayout,
QPushButton,
QWidget,
)
class ToggleButtonImage(QPushButton):
def __init__(self, imgname: str, tooltip_str: str):
super().__init__()
self.setIcon(QIcon(imgname))
self.setIconSize(QSize(32, 32))
self.setToolTip(tooltip_str)
self.setCheckable(True)
self.setAutoExclusive(True)
class Example(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle('果物選択')
hbox = QHBoxLayout()
self.setLayout(hbox)
pb_apple = ToggleButtonImage('fruit_apple.png', '林檎')
hbox.addWidget(pb_apple)
pb_apple.toggle()
pb_grape = ToggleButtonImage('fruit_grape.png', '葡萄')
hbox.addWidget(pb_grape)
pb_orange = ToggleButtonImage('fruit_orange.png', '蜜柑')
pb_orange.setAutoExclusive(True)
hbox.addWidget(pb_orange)
self.but_group = but_group = QButtonGroup()
but_group.addButton(pb_apple)
but_group.addButton(pb_grape)
but_group.addButton(pb_orange)
but_group.buttonToggled.connect(self.selection_changed)
def selection_changed(self, button, state):
if state:
status = 'オン'
else:
status = 'オフ'
print('「%s」を%sにしました。' % (button.toolTip(), status))
def main():
app = QApplication(sys.argv)
ex = Example()
ex.show()
sys.exit(app.exec())
if __name__ == '__main__':
main()
qt_radiobutton_fruit_2.py の実行例

3つのボタンで同じ設定を繰り返すのを避けるため、QPushButton を継承した ToggleButtonImage クラスを用意しました。

class ToggleButtonImage(QPushButton):
    def __init__(self, imgname: str, tooltip_str: str):
        super().__init__()
        self.setIcon(QIcon(imgname))
        self.setIconSize(QSize(32, 32))
        self.setToolTip(tooltip_str)
        self.setCheckable(True)
        self.setAutoExclusive(True)

ラジオボタンと同じ機能は self.setCheckable(True)self.setAutoExclusive(True) で実現しています。イメージだけを表示する代わりに、イメージのサイズを少し大きくしました。

QButtonGroup は、QRadioButton の時と同じように使えます。出力例は省略しましたが、selection_changed メソッドでは(ラジオボタンに表示していた文字列の代わりに)ツールチップに設定した文字列を出力するようにしています。

参考サイト

  1. かわいいフリー素材集 いらすとや
  2. QAbstractButton - Qt for Python
  3. QButtonGroup - Qt for Python

 

ブログランキング・にほんブログ村へ bitWalk's - にほんブログ村 にほんブログ村 IT技術ブログ オープンソースへ
にほんブログ村

オープンソース - ブログ村ハッシュタグ
#オープンソース



0 件のコメント: