tkinter - 定义“自定义颜色";颜色选择器 [英] tkinter - define "custom colors" for colorchooser
问题描述
我目前在项目中使用 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屋!