Erstellen Sie mit Python + Qt (PySide) einen Farbwähler für das Farbrad.

Es war unwahrscheinlich und unerwartet, deshalb habe ich ein Widget für den Farbwähler des Farbrads erstellt. Als ich die Verarbeitung auf niedriger Ebene mit C-Sprachkleber beschrieb, wurde sie zunächst in Zeitlupe, wenn sie vergrößert und in der Funktionsprüfung für hochauflösende Monitore angezeigt wurde. Wenn ich die Qt-Bibliothek und den Python-Stil optimierte, funktionierte dies problemlos. Es wurde. Wenn Sie Python verwenden, sollten Sie den Python-Stil lernen.

Die Abstufung des Farbfeldes von Sättigung und Helligkeit in der Mitte wird durch Synthese der beiden Abstufungen von Sättigung und Transparenz realisiert. Dies ist die Methode, die in Bulletin Boards in Übersee eingeführt wurde.

Ich habe mich bei PyPI registriert. Sie können es mit Pip usw. installieren. Ich habe die Quelle auf GitHub registriert. https://github.com/tokyo-noctambulist/colorpicker.git

(Aktualisiert am 07.03.2017) Es wurde ein Fehler behoben, der den α-Wert zerstörte. In Kachel BG geändert, um den α-Wert auf der Farbprobe und dem Farbrad wiederzugeben Ändern Sie den zu kopierenden Wert, wenn Sie die Farbe angeben

Stichprobe

image

In sample.py werden die beiden Farbkreise verknüpft und angezeigt.


Kurze Erklärung

Ich habe mich bei PyPI registriert. Sie können es mit Pip usw. installieren.

function


pip install colorpicker #install

from colorpicker import *

colorCircle = QHueCircleWidget(self)
color = colorCircle.getColor() #Holen Sie sich Farbe
colorCircle.setColor(QColor(255,100,10,200)) #Stellen Sie die Farbe ein

colorCircle.colorChanged.connect(onUpdateColor) #signal-slot

Sie können die Größe mit resize () ändern. Es funktioniert jedoch nur dann ordnungsgemäß, wenn das Seitenverhältnis auf 1: 1 eingestellt ist. (Nicht kompatibel mit elliptischem Zustand orz)


QHueCircleWidget.py


# coding:utf-8
from __future__ import division, print_function, unicode_literals, absolute_import
# noinspection PyUnresolvedReferences
from future_builtins import *

from PySide.QtGui import *
from PySide.QtCore import *

import math

class QHueCircleWidget(QGraphicsView):
    PRESS_NONE = 0
    PRESS_BOX = 1
    PRESS_CIRCLE = 2

    colorChanged = Signal(str)

    def __init__(self, parent):
        super(QHueCircleWidget, self).__init__(parent)
        self.scene = QGraphicsScene(self)
        self.setScene(self.scene)
        self.rectF = None
        self.press_mode = self.PRESS_NONE
        self.color = QColor()
        self.color.setHsv(0, 255, 255, 255)
        self.setColor(self.color)
        self.bg_brush = QBrush(self.create_bg_pixmap())

        # self.setFixedSize(200,200)
        self.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        self.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum)
        self.setMinimumSize(200, 200)


    def drawBackground(self, painter, rect):
        """
        :type rect: QRectF
        :type painter: QPainter
        """
        painter.save()

        painter.translate(rect.center())
        painter.setRenderHint(QPainter.Antialiasing, True)
        self.rectF = rect
        self.rectToParam()
        painter.setPen(QPen(Qt.black, 1))
        # draw select color
        painter.setBrush(self.bg_brush)
        painter.drawEllipse(-self.half_width, -self.half_height, self.width / 8, self.height / 8)
        painter.setBrush(self.color)
        painter.drawEllipse(-self.half_width, -self.half_height, self.width / 8, self.height / 8)
        # hue color circle
        painter.setBrush(self.bg_brush)
        painter.drawEllipse(0 - self.half_width, 0 - self.half_height, self.width, self.height)
        color = QColor()
        gradient = QConicalGradient(0, 0, 0)
        for _ in range(11):
            color.setHsv((10 - _) * 36, 255, 255, self.color.alpha())
            gradient.setColorAt(0.1 * _, color)
        painter.setBrush(gradient)
        painter.drawEllipse(0 - self.half_width, 0 - self.half_height, self.width, self.height)
        # center delete circle
        mini_circle_width = self.width * 3 / 4
        mini_circle_height = self.height * 3 / 4
        painter.setBrush(QPalette().brush(QPalette.Midlight))
        painter.drawEllipse(0 - mini_circle_width / 2, 0 - mini_circle_height / 2 , mini_circle_width, mini_circle_height)
        # center box saturation
        gradient = QLinearGradient(-self.quarter_width, 0, self.quarter_width, 0)
        color.setHsv(self.color.hue(), 0, 255, 255)
        gradient.setColorAt(0.0, color)
        color.setHsv(self.color.hue(), 255, 255, 255)
        gradient.setColorAt(1.0, color)
        painter.setBrush(gradient)
        painter.drawRect(-self.quarter_width, -self.quarter_height, self.half_width, self.half_height)

        painter.restore()

    def drawForeground(self, painter, rect):
        """
        :type rect: QRectF
        :type painter: QPainter
        """
        painter.save()

        painter.translate(rect.center())
        painter.setRenderHint(QPainter.Antialiasing, True)
        # center box value
        gradient = QLinearGradient(0, -self.quarter_height, 0, self.quarter_height)
        color = QColor()
        color.setHsv(0, 0, 0, 0)
        gradient.setColorAt(0.0, color)
        color.setHsv(0, 0, 0, 255)
        gradient.setColorAt(1.0, color)
        painter.setBrush(gradient)
        painter.drawRect(-self.quarter_width, -self.quarter_height, self.half_width, self.half_height)
        # lupe for Saturation / Value
        painter.setPen(QPen(QColor(255, 255, 255, 255), 1))
        painter.drawEllipse(self.sv_x - 3, self.sv_y - 3, 7, 7)
        painter.setPen(QPen(QColor(0, 0, 0, 255), 1))
        painter.drawEllipse(self.sv_x - 2, self.sv_y - 2, 5, 5)
        # lupe for Hue
        painter.setPen(QPen(QColor(0, 0, 0, 255), 1))
        painter.setBrush(QColor(255, 255, 255, 0))
        painter.rotate(self.color.hue())
        painter.drawRect(self.width * 3 / 8, -4, self.width / 8, 8)

        painter.restore()

    def mouseMoveEvent(self, event):
        self.clickToColor(event)

    def mousePressEvent(self, event):
        if event.button() == Qt.LeftButton:
            self.rectToParam()
            if self.hitBox(event.x(), event.y()):
                self.press_mode = self.PRESS_BOX
                self.clickToColor(event)
            elif self.hitCircle(event.x(), event.y()):
                self.press_mode = self.PRESS_CIRCLE
                self.clickToColor(event)
            else:
                self.press_mode = self.PRESS_NONE

    def clickToColor(self, event):
        if self.press_mode == self.PRESS_BOX:
            self.clickToBox(event)
        elif self.press_mode == self.PRESS_CIRCLE:
            self.clickCircle(event)

        self.colorChanged.emit('colorChanged')
        self.scene.update()

    def hitBox(self, x, y):
        rect = QRect(self.quarter_width, self.quarter_height, self.width * 2 / 4, self.height * 2 / 4)
        return rect.contains(x, y)

    def hitCircle(self, x, y):
        path = QPainterPath()
        path.addEllipse(0, 0, self.width, self.height)

        path2 = QPainterPath()
        path2.addEllipse(self.quarter_width / 2., self.quarter_height / 2., self.width / 4. * 3., self.height / 4. * 3.)

        pos = QPointF(x, y)
        return path.contains(pos) and not path2.contains(pos)

    def clickToBox(self, event):
        if not self.hitBox(event.x(), event.y()):
            return

        x = event.x()
        y = event.y()

        col_sat = 255 * (x - self.quarter_width) / self.half_width
        col_sat = 0 if col_sat < 0 else col_sat
        col_sat = 255 if col_sat > 255 else col_sat

        col_val = 255 * (self.half_height - (y - self.quarter_height)) / self.half_height
        col_val = 0 if col_val < 0 else col_val
        col_val = 255 if col_val > 255 else col_val

        self.color.setHsv(
            self.color.hue(),
            col_sat,
            col_val,
            self.color.alpha()
        )
        self.sv_x = x - self.half_width
        self.sv_y = y - self.half_height

    def clickCircle(self, event):
        x = event.x()
        y = event.y()

        k = int(math.degrees(math.atan2(x - self.half_width, self.half_height - y)))
        self.color.setHsv(
            (k - 90) % 360,
            self.color.saturation(),
            self.color.value(),
            self.color.alpha()
        )
        self.hue_x = x - self.half_width
        self.hue_y = y - self.half_height

    def getColor(self):
        return(self.color)

    def setColor(self, color):
        self.color = QColor(color)
        if self.rectF == None:
            self.sv_x = 0
            self.sv_y = 0
            self.hue_x = 0
            self.hue_y = 0
            self.scene.update()
        else:
            self.rectToParam()
            # SV
            self.sv_x = color.saturation() * self.half_width / 255 - self.quarter_width
            self.sv_y = (255 - color.value()) * self.half_height / 255 - self.quarter_height
            # Hue
            radian = ((color.hue()) % 360) * math.pi / 180
            self.hue_x = math.cos(radian) * self.half_width
            self.hue_y = math.sin(radian) * self.half_height
        self.scene.update()

    def rectToParam(self):
        if self.rectF == None:
            rect = QRectF(0, 0, 200, 200)
        else:
            rect = self.rectF

        self.width = rect.toRect().width()
        self.half_width = self.width / 2
        self.quarter_width = self.width / 4

        self.height = rect.toRect().height()
        self.half_height = self.height / 2
        self.quarter_height = self.height / 4

    @staticmethod
    def create_bg_pixmap(color1=None, color2=None):
        """
        :rtype: QPixmap
        """
        pixmap = QPixmap(QSize(16, 16))
        color1 = color1 or QColor(128, 128, 128)
        color2 = color2 or QColor(168, 168, 168)

        painter = QPainter(pixmap)
        painter.save()
        brush1 = QBrush(color1)
        brush2 = QBrush(color2)
        painter.fillRect(0, 0, 8, 8, brush1)
        painter.fillRect(8, 8, 8, 8, brush1)
        painter.fillRect(8, 0, 8, 8, brush2)
        painter.fillRect(0, 8, 8, 8, brush2)
        painter.restore()
        painter.end()

        return pixmap

sample.py


from __future__ import division, print_function, unicode_literals, absolute_import

from PySide.QtGui import *
from PySide.QtCore import *
import sys

class MainWindow(QMainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.resize(700, 500)

        self.colorCircle1 = QHueCircleWidget(self)

        self.colorCircle2 = QHueCircleWidget(self)
        self.colorCircle2.resize(400, 400)
        self.colorCircle2.move(260, 50)

        # alpha color sample
        color = QColor(255, 0, 0, 100)
        self.colorCircle1.setColor(color)
        self.colorCircle2.setColor(color)

        self.colorCircle1.colorChanged.connect(self.onUpdateColor1)
        self.colorCircle2.colorChanged.connect(self.onUpdateColor2)

    @Slot()
    def onUpdateColor1(self):
        color = self.colorCircle1.getColor()
        self.colorCircle2.setColor(color)

    @Slot()
    def onUpdateColor2(self):
        color = self.colorCircle2.getColor()
        self.colorCircle1.setColor(color)

def main():
    app = QApplication(sys.argv)
    main_window = MainWindow()
    main_window.show()
    sys.exit(app.exec_())

if __name__ == "__main__":
    main()

Recommended Posts

Erstellen Sie mit Python + Qt (PySide) einen Farbwähler für das Farbrad.
Erstellen Sie eine Farbleiste mit Python + Qt (PySide)
Erstellen Sie mit Python + Qt (PySide) ein farbspezifisches Widget.
Erstellen Sie einen Twitter-BOT mit dem GoogleAppEngine SDK für Python
Erstellen Sie mit Minette für Python einen LINE BOT
Füllen Sie den Hintergrund mit einer einzigen Farbe mit OpenCV2 + Python
Erstellen Sie in Docker eine Ebene für AWS Lambda Python
Erstellen Sie ein Verzeichnis mit Python
Erstellen Sie ein untergeordnetes Konto für die Verbindung mit Stripe in Python
[Python] Erstellen Sie mit Django einen Bildschirm für den HTTP-Statuscode 403/404/500
Erstellen Sie eine virtuelle Umgebung mit Python!
Erstellen Sie eine gestreifte Illusion mit Gammakorrektur für Python3 und openCV3
Die Geschichte, einen Standardtreiber für db mit Python zu erstellen.
Erstellen Sie ein USB-Boot-Ubuntu mit einer Python-Umgebung für die Datenanalyse
Erstellen Sie ein Kompatibilitätsbewertungsprogramm mit dem Zufallsmodul von Python.
Erstellen Sie mit Class einen Python-Funktionsdekorator
Erstellen Sie mit Python + PIL ein Dummy-Image.
Erstellen wir eine virtuelle Umgebung für Python
[Python] Erstellen Sie mit Anaconda eine virtuelle Umgebung
Erstellen wir mit Python eine kostenlose Gruppe
Durchsuche das Labyrinth mit dem Python A * -Algorithmus
Qt für Python App Desktop App
Erstellen Sie mit Python 3.4 einen Worthäufigkeitszähler
[Einführung in die Udemy Python3 + -Anwendung] 47. Verarbeiten Sie das Wörterbuch mit einer for-Anweisung
Erstellen Sie mit dem Python-Anforderungsmodul einen Datensatz mit Anhängen in KINTONE
[Python] Holen Sie sich die Dateien mit Python in den Ordner
Erstellt einen Python-Wrapper für die Qiita-API
Holen Sie sich ein Ticket für einen Themenpark mit Python
Verwenden Sie vorerst Logger mit Python
Vorgehensweise zum Erstellen eines mit Python erstellten LineBot
Erstellen Sie eine Seite, die unbegrenzt mit Python geladen wird
[Hinweis] Erstellen Sie mit Python eine einzeilige Zeitzonenklasse
Sie können auch mit Python problemlos eine GUI erstellen
Erstellen Sie mit Sublime Text3 eine Python3-Build-Umgebung
Erstellen Sie mit Django ein Dashboard für Netzwerkgeräte!
Python: Bereiten Sie einen Serializer für die Klasseninstanz vor:
Schritte zum Erstellen eines Twitter-Bots mit Python
Befehle zum Erstellen einer Python3-Umgebung mit virtualenv
Erstellen Sie mit Python einen Entscheidungsbaum von 0 (1. Übersicht)
Erstellen Sie eine neue Seite im Zusammenfluss mit Python
Erstellen Sie mit Python eine Datei im Photoshop-Format (.psd)
Erstellen Sie einfach eine Python-Konsolenanwendung mit Click
Erstellen Sie ein Übersetzungswerkzeug mit dem Translate Toolkit
Erstellen wir ein einfaches Empfangssystem mit dem serverlosen Python-Framework Chalice und Twilio
Drehen Sie in Python mehrere Listen mit for-Anweisung gleichzeitig
[Einführung in Python] So erhalten Sie den Datenindex mit der for-Anweisung
Erstellen Sie eine saubere Datenbank zum Testen mit FastAPI und führen Sie Unittest of API mit pytest aus
Automatisieren Sie das Entfernen des Hintergrunds für die neuesten Porträts in einem Verzeichnis mit Python und API
Erstellen Sie ein Python-Modul
Führen Sie es vorerst mit CentOS7 + Apache2.4 + Python3.6 aus
So erstellen Sie ein Untermenü mit dem Plug-In [Blender]
[CRUD] [Django] Erstellen Sie eine CRUD-Site mit dem Python-Framework Django ~ 1 ~
[Python] 2 Erstellen Sie eine Risiko-Rendite-Karte für Ihr Asset-Portfolio
Erstellen Sie mit pyenv-virtualenv eine Python-Umgebung für jedes Verzeichnis
[Python] Generieren Sie ValueObject mit dem vollständigen Konstruktor mithilfe von Datenklassen
Lassen Sie uns eine Todo-App mit dem Django REST-Framework erstellen
Warum nicht einfach mit Python eine stilvolle Tabelle erstellen?
Erstellen Sie eine Python-Entwicklungsumgebung mit Vagrant + Ansible + Fabric
Machen Sie mit Python einen Haltepunkt auf der c-Ebene