【问题标题】:tkinter - define "custom colors" for colorchoosertkinter - 为颜色选择器定义“自定义颜色”
【发布时间】:2018-07-20 00:55:57
【问题描述】:

我目前在项目中使用来自tkintercolorchooser,以允许用户选择自定义颜色。最低限度,这可以通过

创建(在 Python 3.x 中)
from tkinter import colorchooser

cp = colorchooser.askcolor()

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

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

【问题讨论】:

  • 我确认颜色选择器 GUI 是特定于平台的。它在 linux (i.imgur.com/rHTIvABl.png) 中看起来非常不同,并且没有自定义颜色部分。
  • @j_4321 很高兴知道 - 特定于平台可能会降低它的选项。
  • Tcl/Tk documentation page for the colorchooser 没有提到任何特定于平台的选项,所以我怀疑是否可以设置自定义颜色。
  • 我也会用这个问题标记tk。虽然自定义颜色似乎是使用循环填充的,但在某种程度上这很奇怪,但在绘画中它们最初是空的(或全白)。
  • @Nae,事实上,you're right 关于一个循环! @ason​​gtoruin,这样的对话框是原生 Windows 对话框,而 tk 是它的包装器。使用自定义颜色选项可以更轻松地为此对话框编写自己的包装器。

标签: python python-3.x tkinter tk


【解决方案1】:

您看到的是常见的Color dialog box,它是本机Windows 对话框。无法在 tkinter 中指定自定义颜色,因为它们是在 lower level 处处理的。

天真的实现(使用ctypes)可能是这样的:

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)

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

【讨论】:

    【解决方案2】:

    不,无法从 tkinter 预填充自定义颜色。

    【讨论】:

      猜你喜欢
      • 2013-07-18
      • 2014-04-11
      • 2020-10-14
      • 2021-10-24
      • 1970-01-01
      • 2013-02-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多