我正在尝试在tkinter自定义标题栏。
使用以下代码:
def move_window(event):
app.geometry('+{0}+{1}'.format(event.x_root, event.y_root))
if __name__ == "__main__":
app = SampleApp()
app.overrideredirect(True)
screen_width = app.winfo_screenwidth()
screen_height = app.winfo_screenheight()
x_coordinate = (screen_width/2) - (1050/2)
y_coordinate = (screen_height/2) - (620/2)
app.geometry("{}x{}+{}+{}".format(1050, 650, int(x_coordinate), int(y_coordinate)))
title_bar = Frame(app, bg='#090909', relief='raised', bd=0, height=20, width=1050)
close_button = Button(title_bar, text='X', command=app.destroy, width=5, bg="#090909", fg="#888", bd=0)
title_bar.place(x=0, y=0)
close_button.place(rely=0, relx=1, x=0, y=0, anchor=NE)
title_bar.bind('<B1-Motion>', move_window)
app.mainloop()
null
我希望能够添加一个最小化按钮。我尝试用
null
此外,移动有一个很大的问题,当你尝试移动窗口时,它会移动窗口,使其左上角位于光标所在的位置。这是非常恼人的,也不是Windows的典型行为。
如果有人知道如何解决这些问题,我们将不胜感激。
编辑:我现在已经成功地制作了一个自定义标题栏,我可以用它来无缝地拖动窗口。我还使应用程序显示在任务栏,以及添加了一个最小化按钮到标题栏。然而,我一直无法让最小化按钮实际工作。
标题栏和所有其他窗口装饰(最大化,最小化和还原按钮以及窗口的任何边缘)由窗口管理器拥有和管理。Tk必须要求窗口管理器对它们执行任何操作,这就是为什么设置应用程序标题是一个
我的建议是停止对抗体制。这就是Windows manager主题的用途,Windows不允许你去搞乱这些主题。如果您真的仍然想走这条路,您可以将windows框架装饰创建为Ttk主题元素,因为它们是当前样式集合的一部分,可以使用vsapi Ttk元素引擎创建。视觉样式API中的一些值:
| Function | Class | ID | Numerical ID |
+-------------+---------+------------------+--------------+
| Minimize | WINDOW | WP_MINBUTTON | 15 |
| Maximize | WINDOW | WP_MAXBUTTON | 17 |
| Close | WINDOW | WP_CLOSEBUTTON | 18 |
| Restore | WINDOW | WP_RESTOREBUTTON | 21 |
我在python中使用了这些元素,就像这样获得了一个closebutton元素,然后可以将其包含在ttk小部件样式中。
style = ttk.Style()
# There seems to be some argument parsing bug in tkinter.ttk so cheat and eval
# the raw Tcl code to add the vsapi element for a pin.
root.eval('''ttk::style element create closebutton vsapi WINDOW 18 {
{pressed !selected} 3
{active !selected} 2
{pressed selected} 6
{active selected} 5
{selected} 4
{} 1
}''')
然而,我怀疑您可能仍然希望避免这些按钮的主题性质,因此您更可能只想使用png图像,并使用画布而不是框架。然后,您可以使用标记绑定来轻松地获取伪标题栏按钮上的事件。
#!/usr/bin/env python3
"""
Q: Trouble making a custom title bar in Tkinter
https://stackoverflow.com/q/49621671/291641
"""
import tkinter as tk
import tkinter.ttk as ttk
from ctypes import windll
GWL_EXSTYLE=-20
WS_EX_APPWINDOW=0x00040000
WS_EX_TOOLWINDOW=0x00000080
def set_appwindow(root):
"""Change the window flags to allow an overrideredirect window to be
shown on the taskbar.
(See https://stackoverflow.com/a/30819099/291641)
"""
hwnd = windll.user32.GetParent(root.winfo_id())
style = windll.user32.GetWindowLongPtrW(hwnd, GWL_EXSTYLE)
style = style & ~WS_EX_TOOLWINDOW
style = style | WS_EX_APPWINDOW
res = windll.user32.SetWindowLongPtrW(hwnd, GWL_EXSTYLE, style)
# re-assert the new window style
root.wm_withdraw()
root.after(10, lambda: root.wm_deiconify())
def create_button_element(root, name, id):
"""Create some custom button elements from the Windows theme.
Due to a parsing bug in the python wrapper, call Tk directly."""
root.eval('''ttk::style element create {0} vsapi WINDOW {1} {{
{{pressed !selected}} 3
{{active !selected}} 2
{{pressed selected}} 6
{{active selected}} 5
{{selected}} 4
{{}} 1
}} -syssize {{SM_CXVSCROLL SM_CYVSCROLL}}'''.format(name,id))
class TitleFrame(ttk.Widget):
"""Frame based class that has button elements at one end to
simulate a windowmanager provided title bar.
The button click event is handled and generates virtual events
if the click occurs over one of the button elements."""
def __init__(self, master, **kw):
self.point = None
kw['style'] = 'Title.Frame'
kw['class'] = 'TitleFrame'
ttk.Widget.__init__(self, master, 'ttk::frame', kw)
@staticmethod
def register(root):
"""Register the custom window style for a titlebar frame.
Must be called once at application startup."""
style = ttk.Style()
create_button_element(root, 'close', 18)
create_button_element(root, 'minimize', 15)
create_button_element(root, 'maximize', 17)
create_button_element(root, 'restore', 21)
style.layout('Title.Frame', [
('Title.Frame.border', {'sticky': 'nswe', 'children': [
('Title.Frame.padding', {'sticky': 'nswe', 'children': [
('Title.Frame.close', {'side': 'right', 'sticky': ''}),
('Title.Frame.maximize', {'side': 'right', 'sticky': ''}),
('Title.Frame.minimize', {'side': 'right', 'sticky': ''})
]})
]})
])
style.configure('Title.Frame', padding=(1,1,1,1), background='#090909')
style.map('Title.Frame', **style.map('TEntry'))
root.bind_class('TitleFrame', '<ButtonPress-1>', TitleFrame.on_press)
root.bind_class('TitleFrame', '<B1-Motion>', TitleFrame.on_motion)
root.bind_class('TitleFrame', '<ButtonRelease-1>', TitleFrame.on_release)
@staticmethod
def on_press(event):
event.widget.point = (event.x_root,event.y_root)
element = event.widget.identify(event.x,event.y)
if element == 'close':
event.widget.event_generate('<<TitleFrameClose>>')
elif element == 'minimize':
event.widget.event_generate('<<TitleFrameMinimize>>')
elif element == 'restore':
event.widget.event_generate('<<TitleFrameRestore>>')
@staticmethod
def on_motion(event):
"""Use the relative distance since the last motion or buttonpress event
to move the application window (this widgets toplevel)"""
if event.widget.point:
app = event.widget.winfo_toplevel()
dx = event.x_root - event.widget.point[0]
dy = event.y_root - event.widget.point[1]
x = app.winfo_rootx() + dx
y = app.winfo_rooty() + dy
app.wm_geometry('+{0}+{1}'.format(x,y))
event.widget.point=(event.x_root,event.y_root)
@staticmethod
def on_release(event):
event.widget.point = None
class SampleApp(tk.Tk):
"""Example basic application class"""
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
self.wm_geometry('320x240')
def main():
app = SampleApp()
TitleFrame.register(app)
app.overrideredirect(True)
screen_width = app.winfo_screenwidth()
screen_height = app.winfo_screenheight()
x_coordinate = (screen_width/2) - (1050/2)
y_coordinate = (screen_height/2) - (620/2)
app.geometry("{}x{}+{}+{}".format(1050, 650, int(x_coordinate), int(y_coordinate)))
title_bar = TitleFrame(app, height=20, width=1050)
title_bar.place(x=0, y=0)
app.bind('<<TitleFrameClose>>', lambda ev: app.destroy())
app.bind('<<TitleFrameMinimize>>', lambda ev: app.wm_iconify())
app.bind('<Key-Escape>', lambda ev: app.destroy())
app.after(10, lambda: set_appwindow(app))
app.mainloop()
if __name__ == "__main__":
main()
null
我正在创建一个自定义标记库,并希望在我的一个组件中使用它。我已经创建了一个包,其中包括扩展TagSupport类的标记hello类,我创建了标记。我的资源文件夹下的tld文件 在我的pom中。xml,我使用了资源标记来包含我的。生成的jar文件中的tld文件。 这是我的java类和tld文件 标记类别:- 我还成功地在felix控制台中安装了该捆绑包,没有出现任何错误。然后,我在jsp中编写了自定
问题内容: 我希望在Java Swing桌面应用程序中有一个自定义的标题栏。最好的方法是什么?通过在JFrame的构造函数中使用以下代码,可以使用“标题栏”: 但是,如何自定义呢?是否可以覆盖任何 UI委托 ,还是必须从头开始实现自己的标题栏? 我想要类似Lawson Smart Office的东西: 问题答案: 您可以在Substance外观(镜像源)中看到一个示例。在代码中搜索Substanc
默认情况下,Navicat Monitor 从受监控的实例收集一组预设的服务器指标。你可能想要添加自己的查询,以收集特定实例的一些自定义性能指标,并在指标值超过某些阈值和持续时间时接收有关自定义数据的警报。若要配置自定义指标,请前往“配置”->“自定义指标”。 创建自定义指标和警报 在自定义指标页面中,点击“+ 新建自定义指标”。 【步骤一】输入自定义指标的定义: 指标名 输入自定义指标的名。 描
问题内容: 我正在尝试在javaFX中创建自定义光标。这是我的代码: Windows 8.1的游标创建无效吗? 问题答案: 检出ImageCursor.getBestSize()方法和ImageCursor.getMaximumColors()并查看它们返回的内容,然后尝试匹配最佳大小和最大颜色的自定义光标图像。对于Windows 8.1,这很可能是32x32的光标。 这是来自javadoc 的引
我一直在为我的项目使用tkinter滚动条。但是,当我使用属性troughcolor时,滚动条的颜色不会改变。所以,我想为tkinter和python制作一个自定义滚动条,可以用来在框架中滚动。然后我将添加颜色到这个自定义滚动条。有没有办法这样做?下面是我的代码:
我使用这段代码来最大化和恢复我的自定义表单。但是当窗体最大化时,它仍然可以拖动,我使用计时器来拖动窗体。