PyQt で画像のビューアを作る 12

色表示用のwidgetを作った

190710

  • 色をRGBとHSV両方で表示してHSVはスライダーで値を変えれる
  • ↓ widgetクラスのpy と、このwidgetを使ったpyファイル
from PyQt5.QtWidgets import QApplication,QWidget,QLineEdit,QLabel,QSlider
from PyQt5.QtGui import QBrush , QColor,QPainter
from PyQt5.QtCore import pyqtSignal,QPoint,QRect,Qt

class Ui_Form(QWidget):
    colorchanged = pyqtSignal( QColor )
    def __init__(self,parent ):
        super().__init__(parent)
        self.resize(267, 83)
        self.lineEdit = QLineEdit(self)
        self.lineEdit.setGeometry(QRect(42, 20, 31, 20))
        self.lineEdit.setAlignment(Qt.AlignCenter)
        self.lineEdit.setObjectName("lineEdit")
        self.label = QLabel(self)
        self.label.setGeometry(QRect(45, 0, 21, 16))
        self.label.setObjectName("label")
        self.lineEdit_2 = QLineEdit(self)
        self.lineEdit_2.setGeometry(QRect(42, 40, 31, 20))
        self.lineEdit_2.setAlignment(Qt.AlignCenter)
        self.lineEdit_2.setObjectName("lineEdit_2")
        self.lineEdit_3 = QLineEdit(self)
        self.lineEdit_3.setGeometry(QRect(42, 60, 31, 20))
        self.lineEdit_3.setAlignment(Qt.AlignCenter)
        self.lineEdit_3.setObjectName("lineEdit_3")
        self.hSlider = QSlider(self)
        self.hSlider.setGeometry(QRect(80, 10, 160, 16))
        self.hSlider.setMaximum(359)
        self.hSlider.setOrientation(Qt.Horizontal)
        self.hSlider.setObjectName("hSlider")
        self.hSlider_2 = QSlider(self)
        self.hSlider_2.setGeometry(QRect(80, 35, 160, 16))
        self.hSlider_2.setMaximum(255)
        self.hSlider_2.setOrientation(Qt.Horizontal)
        self.hSlider_2.setObjectName("hSlider_2")
        self.hSlider_3 = QSlider(self)
        self.hSlider_3.setGeometry(QRect(80, 60, 160, 16))
        self.hSlider_3.setMaximum(255)
        self.hSlider_3.setOrientation(Qt.Horizontal)
        self.hSlider_3.setObjectName("hSlider_3")
        self.label_2 = QLabel(self)
        self.label_2.setGeometry(QRect(245, 10, 21, 16))
        self.label_2.setAlignment(Qt.AlignCenter)
        self.label_2.setObjectName("label_2")
        self.label_3 = QLabel(self)
        self.label_3.setGeometry(QRect(245, 35, 21, 16))
        self.label_3.setAlignment(Qt.AlignCenter)
        self.label_3.setObjectName("label_3")
        self.label_4 = QLabel(self)
        self.label_4.setGeometry(QRect(245, 60, 21, 16))
        self.label_4.setAlignment(Qt.AlignCenter)
        self.label_4.setObjectName("label_4")

        self.retranslateUi()
        self.lineEdit.textEdited['QString'].connect(self.getRGB)
        self.lineEdit_2.textEdited['QString'].connect(self.getRGB)
        self.lineEdit_3.textEdited['QString'].connect(self.getRGB)
        self.hSlider.valueChanged['int'].connect(self.getHSV)
        self.hSlider_2.valueChanged['int'].connect(self.getHSV)
        self.hSlider_3.valueChanged['int'].connect(self.getHSV)
        # QtCore.QMetaObject.connectSlotsByName(Form)

        self.color=QColor(255,255,255)
        self.setHSV()
    def retranslateUi(self):
        _translate = QApplication.translate
        self.setWindowTitle(_translate("Form", "Form"))
        self.lineEdit.setText(_translate("Form", "255"))
        self.label.setText(_translate("Form", "RGB"))
        self.lineEdit_2.setText(_translate("Form", "255"))
        self.lineEdit_3.setText(_translate("Form", "255"))
        self.label_2.setText(_translate("Form", "359"))
        self.label_3.setText(_translate("Form", "255"))
        self.label_4.setText(_translate("Form", "255"))

    def setcolor(self,c):
        self.color=c
        self.update()
        self.setRGB()
        self.setHSV()

    def setRGB(self):
        self.lineEdit.setText( str(self.color.red()))
        self.lineEdit_2.setText( str(self.color.green()))
        self.lineEdit_3.setText( str(self.color.blue()))
    def getRGB(self):
        self.color = QColor( int(self.lineEdit.text()),int(self.lineEdit_2.text()),int(self.lineEdit_3.text()))
        # self.update()
        self.setHSV()
        # self.colorchanged.emit(self.color) 

    def setHSV(self):
        h,s,v,a = self.color.getHsv()
        self.hSlider.setValue( h)
        self.hSlider_2.setValue( s)
        self.hSlider_3.setValue( v)
        self.label_2.setText(str(h))
        self.label_3.setText(str(s))
        self.label_4.setText(str(v))
    def setHSV2(self):
        h,s,v,a = self.color.getHsv()
        self.label_2.setText(str(h))
        self.label_3.setText(str(s))
        self.label_4.setText(str(v))
    def getHSV(self):
        self.color= QColor( QColor.fromHsv( self.hSlider.value() , self.hSlider_2.value() ,self.hSlider_3.value() ))
        self.setRGB()
        self.setHSV2()
        self.update()
        self.colorchanged.emit(self.color) 

    def paintEvent(self,e):
        painter= QPainter()
        painter.begin(self) 
        painter.setBrush( self.color )
        painter.drawRect( QRect( QPoint(0,0),QPoint(40,80) ))
        painter.end() 
import sys
from PyQt5.QtWidgets import QApplication,QMainWindow
from color_widget import Ui_Form

class main(QMainWindow):
	def __init__(self):
		super().__init__()
		self.resize(280,150)
		self.color=Ui_Form(self)
		self.color.colorchanged.connect(self.get)
		
	def get(self,c):
		print(c)


	
app = QApplication(sys.argv)
main = main()
main.show()
sys.exit(app.exec_())

カスタムwidget

  • 前から作ってみたかった(・∀・)ノ
  • widgetの派生クラスを作るのは普通のことだけど、親とのやりとりがしたい場合は親に受けの関数を作ってそれを呼んでいた
    でもそうゆーのってオブジェクト指向的には非推奨だよね(たぶん)
    そのためにsignalがある
    なので今回のテーマの一つはシグナルの実装
  • 理屈はまだ今ひとつだけど、webで調べたとおりにやったら無事出来ました
    簡単だったので、時間があったら今まで書いたクラスも書き換えたくなってきた
  • 単なる派生クラスではなくていろんなwidgetを組み合わせてあるのでダイアログに近いのかもしれない
    常にメインウインドウに貼り付けておくつもりなのでwidgetで良いと思うがまあどっちでも良い

用途

  • ホワイトポイント変換で、ターゲットを白以外にしたかった
    気に入った色があったらそれを保存しておいてその色に合わせるって事、ずっとやりたかった
    その際に取得した色とターゲットになる色の両方の微調整が必要になる
    微調整の仕組みを作って二つ配置すればいいだろうってことでwidget化した

Qtのこと

  • 本体のenhancerを作るなかで既にHSV変換は実装してたんだけど、pythonのcolorsysモジュールを使っていた
    今回Qtにもあって良いよなあと思い調べたら、QColorクラスでそもそも実装してあって、この方が使いやすい
  • HSV値をpythonは 0-1 の浮動小数点で扱うので 0-255 のrgbとの変換が必要だけど、Qtは整数値で扱えるのでコードしやすい
    公式ドキュメントにはHSVの説明もあって勉強になる
    Hは360度の円、値は 0-359 なんだね~
  • QColorだが、RGBを取り出すのに QColor[0] としたら怒られた
    QColor.red() が正解
    ちゃんとオブジェクトになってるんだね、納得です
    今まで色はQColorにしたり単純なリストにしたりタプルにしたりしてたけど、QColorで統一した方がわかりやすいかなとも思った

バグ

  • エディットボックスにはRGB値が表示してあるが、任意の数値も入力できるようにした。しかしHSV変換のスライダールーチンをいじってるうちに動作が変になってきてうまく動かない
  • 同じくエディットボックスだが、データを削除すると落ちる(・∀・)ノ
  • エディットボックスとスライダーの両方で色を変えれるようにしたんだけど連携が難しい
    スライダーをRGBとHSVで切り替えた方が良いかもしれない

→ 戻る PyQt で画像のビューア

END

Close