PySide6で色選択ボタンを作ってみた

2023/10/04 categories:Python| tags:Python|PySide6|ColorSelectButton|

動作イメージ

PySide6で、ドロップダウンで色の選択ボタンの一覧を表示するボタンを作ってみました。エクセルの色の選択ボタンのように、下三角のマークをクリックすると代表的な色の一覧が表示されます。クリックした色のカラーネームが確認できるようにQLineEditにカラーネームを表示しています。other colorのボタンをクリックすると色選択ダイアログが表示されます。

ソースコード

from PySide6 import QtWidgets, QtCore, QtGui


class ColorSelectButton(QtWidgets.QToolButton):

    color_selected = QtCore.Signal(str)

    def __init__(self) -> None:
        super().__init__()
        self.color_name = '#ffffff'
        self.setPopupMode(self.ToolButtonPopupMode.MenuButtonPopup)
        self.setIconSize(QtCore.QSize(16, 16))
        self.setSizePolicy(QtWidgets.QSizePolicy.Policy.Minimum, QtWidgets.QSizePolicy.Policy.Minimum)
        self.setMenu(QtWidgets.QMenu(self))
        self.menu().setLayout(QtWidgets.QGridLayout())
        self.menu().layout().setContentsMargins(1, 1, 1, 1)
        self.menu().layout().setSpacing(1)

        names = [ c for c in QtCore.Qt.GlobalColor if not c.name in ['color0', 'color1', 'transparent'] ]
        for i, c in enumerate(names):
            button = Button( QtGui.QColor(c.name).name(), self.set_button_color )
            self.menu().layout().addWidget(button, int(i/5), int(i%5), 1, 1)
        
        button = Button('#ddd', self.show_color_dialog)
        button.setSizePolicy(QtWidgets.QSizePolicy.Policy.MinimumExpanding, QtWidgets.QSizePolicy.Policy.MinimumExpanding)
        button.setText('other color')
        self.menu().layout().addWidget(button, 3, 2, 1, 3)
        self.clicked.connect( lambda : self.color_selected.emit(self.color_name) )
        self.color_selected.connect(print)

    def set_button_color(self):
        self.color_name = self.sender().color_name
        self.setStyleSheet( self.button_style( self.color_name ) )
        self.menu().close()
        self.clicked.emit()
        
    def show_color_dialog(self):
        color = QtWidgets.QColorDialog.getColor()
        if color.isValid():
            self.color_name = color.name()
            self.setStyleSheet( self.button_style( self.color_name ) )
        
    def button_style(self, color_name):
        color = QtGui.QColor(color_name)
        r0, g0, b0 = min(color.red() * 1.5, 255), min(color.green() * 1.5, 255), min(color.blue() * 1.5, 255)
        r1, g1, b1 = min(color.red() * 2.0, 255), min(color.green() * 2.0, 255), min(color.blue() * 2.0, 255)
        hover   = ' QToolButton:hover   { background-color: ' + QtGui.QColor(r0, g0, b0).name() + '; } '
        pressed = ' QToolButton:pressed { background-color: ' + QtGui.QColor(r1, g1, b1).name() + '; } '
        style_sheet = '''
        QToolButton {{
            border: 1px solid #d6d6d6;
            border-radius: 2px;
            background-color: {};
            padding: 2px 8px;
        }}'''.format( color.name() )
        return style_sheet + hover + pressed


class Button(QtWidgets.QToolButton):
    def __init__(self, color_name, slot) -> None:
        super().__init__()
        self.color_name = color_name
        self.setStyleSheet(
            'QToolButton { background-color: ' + color_name + '; padding: 2px 8px; border-radius: 2px; border: 1px solid #aaa; }'
            'QToolButton:hover { border: 4px solid #FFAA33; }'
        )
        self.clicked.connect(slot)



if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)
    linedit = QtWidgets.QLineEdit()
    color_select_button = ColorSelectButton()
    color_select_button.color_selected.connect(linedit.setText)
    w = QtWidgets.QWidget()
    w.setLayout(QtWidgets.QVBoxLayout())
    w.layout().addWidget(linedit)
    w.layout().addWidget(color_select_button)
    w.show()
    app.exec()

Share post

Related Posts

コメント