tkinter - 定义“自定义颜色";颜色选择器 [英] tkinter - define "custom colors" for colorchooser

查看:114
本文介绍了tkinter - 定义“自定义颜色";颜色选择器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我目前在项目中使用 tkinter 中的 colorchooser 来允许用户选择自定义颜色.至少,这可以通过

I am currently using a colorchooser from tkinter in a project to allow the user to choose a custom colour. Minimally, this can be created (in Python 3.x) through

from tkinter import colorchooser

cp = colorchooser.askcolor()

当这个窗口出现时(至少在 Windows 中),有一个名为自定义颜色"的部分

When this window appears (in Windows at least), there is a section called "Custom colors"

有什么方法可以让我用我选择的颜色预先填充这个部分?

Is there any way that I can pre-populate this section with colours of my choosing?

推荐答案

你看到的是常见的 颜色对话框,Windows 原生对话框.无法在 tkinter 中指定自定义颜色,因为它们是在 较低级别.

What you see is the common Color dialog box, which is native Windows dialog. It's not possible to specify custom colors within tkinter, because they're handled at a lower level.

简单的实现(使用 ctypes)可能是这样的:

The naive implementation (using ctypes) could be something like this:

import ctypes
import ctypes.wintypes as wtypes


class CHOOSECOLOR(ctypes.Structure):
    """" a class to represent CWPRETSTRUCT structure
    https://msdn.microsoft.com/en-us/library/windows/desktop/ms646830(v=vs.85).aspx """

    _fields_ = [('lStructSize', wtypes.DWORD),
                ('hwndOwner', wtypes.HWND),
                ('hInstance', wtypes.HWND),
                ('rgbResult', wtypes.COLORREF),
                ('lpCustColors', ctypes.POINTER(wtypes.COLORREF)),
                ('Flags', wtypes.DWORD),
                ('lCustData', wtypes.LPARAM),
                ('lpfnHook', wtypes.LPARAM),
                ('lpTemplateName', ctypes.c_char_p)]


class ColorChooser:
    """ a class to represent Color dialog box
    https://msdn.microsoft.com/en-gb/library/windows/desktop/ms646912(v=vs.85).aspx """
    CC_SOLIDCOLOR = 0x80
    CC_FULLOPEN = 0x02
    custom_color_array = ctypes.c_uint32 * 16
    color_chooser = ctypes.windll.Comdlg32.ChooseColorW

    def to_custom_color_array(self, custom_colors):
        custom_int_colors = self.custom_color_array()

        for i in range(16):
            custom_int_colors[i] = rgb_to_int(*custom_colors[i])

        return custom_int_colors

    def askcolor(self, custom_colors):
        struct = CHOOSECOLOR()

        ctypes.memset(ctypes.byref(struct), 0, ctypes.sizeof(struct))
        struct.lStructSize = ctypes.sizeof(struct)
        struct.Flags = self.CC_SOLIDCOLOR | self.CC_FULLOPEN
        struct.lpCustColors = self.to_custom_color_array(custom_colors)

        if self.color_chooser(ctypes.byref(struct)):
            result = int_to_rgb(struct.rgbResult)
        else:
            result = None

        return result


def rgb_to_int(red, green, blue):
    return red + (green << 8) + (blue << 16)


def int_to_rgb(int_color):
    red = int_color & 255
    green = (int_color >> 8) & 255
    blue = (int_color >> 16) & 255

    return red, green, blue

colors = [(250, 0, 0), (0, 250, 0), (0, 0, 250), (255, 255, 255)] * 4

chooser = ColorChooser()
result_color = chooser.askcolor(colors)
print(result_color)

请记住,有扩展的空间,例如,在调用之间保留自定义颜色数组并支持十六进制颜色/任意数组长度.

Remember, that there's a room for expansion, for example, preserving the custom color array between calls and supporting of hex colors/arbitrary array length.

这篇关于tkinter - 定义“自定义颜色";颜色选择器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆