--- Title: PyQt で画像のビューアを作る 12 Author: yamasyuh68 Web: https://mimemo.io/m/Awa3QlLyxq41jvq --- # 色表示用のwidgetを作った 190710 https://live.staticflickr.com/65535/48249478676_84b814239c.jpg - 色を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 で画像のビューア](https://mimemo.io/m/QORbW4qkvOoda0N)