- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试使用鼠标来选择和取消选择多个项目。我有它的工作,但是当用户快速移动鼠标时会出现问题。当鼠标快速移动时,一些项目会被跳过并且根本没有被选中。我一定是走错了路。
更新 1:
我决定使用我自己的选择系统,但我得到了与上面相同的结果。当鼠标快速移动时,某些项目会被跳过,因此它们没有添加正确的颜色标签并保持不变。如果鼠标缓慢移动,所有项目都会被正确选择。下面是新代码和问题的另一个图像。
更新 2:我已经解决了这个问题并发布了工作代码只是为了完整性和将来帮助其他人。我最终使用了我自己的选择系统而不是内置的选择系统。
import tkinter as tk
import tkinter.ttk as ttk
class App(tk.Tk):
def __init__(self):
super().__init__()
self.title('Treeview Demo')
self.geometry('300x650')
self.rowconfigure(0, weight=1)
self.columnconfigure(0, weight=1)
tv = self.tv = ttk.Treeview(self)
tv.heading('#0', text='Name')
# Populate tree with test data.
for idx in range(0, 4):
tv.insert('', idx, f'!{idx}', text=f'Item {idx+1}', tags='TkTextFont', open=1)
iid = f'!{idx}_!{idx}'
tv.insert(f'!{idx}', '0', iid, text=f'Python {idx+1}', tags='TkTextFont', open=1)
for i in range(0, 5):
tv.insert(iid, f'{i}', f'{iid}_!{i}', text=f'Sub item {i+1}', tags='TkTextFont')
tv.grid(sticky='NSEW')
self.active_item = None
def motion(_):
x, y = tv.winfo_pointerxy()
item = tv.identify('item', x - tv.winfo_rootx(), y - tv.winfo_rooty())
if not item or item == self.active_item:
return
if not self.active_item:
self.active_item = item
tv.selection_toggle(item)
self.active_item = item
def escape(_):
tv.selection_remove(tv.selection())
def button_press(_):
self.bind('<Motion>', motion)
def button_release(_):
self.unbind('<Motion>')
self.active_item = None
self.bind('<Escape>', escape)
self.bind('<Button-1>', button_press)
self.bind('<ButtonRelease-1>', button_release)
def main():
app = App()
app.mainloop()
if __name__ == '__main__':
main()
第二次尝试:
import tkinter as tk
import tkinter.ttk as ttk
import tkinter.font as tkfont
class App(tk.Tk):
def __init__(self):
super().__init__()
self.title('Treeview Demo')
self.geometry('700x650')
self.rowconfigure(0, weight=1)
self.columnconfigure(0, weight=1)
tv = self.tv = ttk.Treeview(self)
tv.heading('#0', text='Name')
tv.tag_configure('odd', background='#aaaaaa')
tv.tag_configure('even', background='#ffffff')
tv.tag_configure('selected_odd', background='#25a625')
tv.tag_configure('selected_even', background='#b0eab2')
tag = 'odd'
# Populate tree with test data.
for idx in range(0, 4):
tag = 'even' if tag == 'odd' else 'odd'
tv.insert('', idx, f'!{idx}', text=f'Item {idx+1}', open=1, tags=(tag,))
tag = 'even' if tag == 'odd' else 'odd'
iid = f'!{idx}_!{idx}'
tv.insert(f'!{idx}', '0', iid, text=f'Python {idx+1}', open=1, tags=(tag,))
for i in range(0, 5):
tag = 'even' if tag == 'odd' else 'odd'
tv.insert(iid, i, f'{iid}_!{i}', text=f'Sub item {i+1}', tags=(tag,))
tv.config(selectmode="none")
tv.grid(sticky='NSEW')
dw = tk.Toplevel()
dw.overrideredirect(True)
dw.wait_visibility(self)
dw.wm_attributes('-alpha', 0.2)
dw.wm_attributes("-topmost", True)
dw.config(bg='#00aaff')
dw.withdraw()
self.selected = False
self.active_item = None
def motion(event):
x, y = self.winfo_pointerxy()
width = event.x-self.anchor_x
height = event.y-self.anchor_y
if width < 0:
coord_x = event.x+self.winfo_rootx()
width = self.anchor_x - event.x
else:
coord_x = self.anchor_x+self.winfo_rootx()
if coord_x+width > self.winfo_rootx()+self.winfo_width():
width -= (coord_x+width)-(self.winfo_rootx()+self.winfo_width())
elif x < self.winfo_rootx():
width -= (self.winfo_rootx() - x)
coord_x = self.winfo_rootx()
if height < 0:
coord_y = event.y+self.winfo_rooty()
height = self.anchor_y - event.y
else:
coord_y = self.anchor_y+self.winfo_rooty()
if coord_y+height > self.winfo_rooty()+self.winfo_height():
height -= (coord_y+height)-(self.winfo_rooty()+self.winfo_height())
elif y < self.winfo_rooty():
height -= (self.winfo_rooty() - y)
coord_y = self.winfo_rooty()
dw.geometry(f'{width}x{height}+{coord_x}+{coord_y}')
item = tv.identify('item', coord_x, coord_y-40)
if not item or item == self.active_item:
self.active_item = None
return
self.active_item = item
tags = list(tv.item(item, 'tags'))
if 'odd' in tags:
tags.pop(tags.index('odd'))
tags.append('selected_odd')
if 'even' in tags:
tags.pop(tags.index('even'))
tags.append('selected_even')
tv .item(item, tags=tags)
def escape(_=None):
for item in tv.tag_has('selected_odd'):
tags = list(tv.item(item, 'tags'))
tags.pop(tags.index('selected_odd'))
tags.append('odd')
tv.item(item, tags=tags)
for item in tv.tag_has('selected_even'):
tags = list(tv.item(item, 'tags'))
tags.pop(tags.index('selected_even'))
tags.append('even')
tv.item(item, tags=tags)
def button_press(event):
if self.selected and not event.state & 1 << 2:
escape()
self.selected = False
dw.deiconify()
self.anchor_item = tv.identify('item', event.x, event.y-40)
self.anchor_x, self.anchor_y = event.x, event.y
self.bind('<Motion>', motion)
self.selected = True
def button_release(event):
dw.withdraw()
dw.geometry('0x0+0+0')
self.unbind('<Motion>')
self.bind('<Escape>', escape)
self.bind('<Button-1>', button_press)
self.bind('<ButtonRelease-1>', button_release)
def main():
app = App()
app.mainloop()
if __name__ == '__main__':
main()
最佳答案
工作示例:
在 Windows 和 Linux 中测试和工作
更新:我已经更新了代码,一切都在 Windows 和 Linux 中工作,尽管在 Windows 中,蓝色透明窗口在从右到左调整大小时会抖动,从左到右很好。在 Linux 中,不知道为什么会发生抖动?如果有人能让我知道下面的代码是否适用于 MacOS,那也很棒。
import tkinter as tk
import tkinter.ttk as ttk
import tkinter.font as tkfont
class Treeview(ttk.Treeview):
def __init__(self, parent, **kwargs):
super().__init__(parent, **kwargs)
self.root = parent.winfo_toplevel()
self.selected_items = []
self.origin_x = \
self.origin_y = \
self.active_item = \
self.origin_item = None
sw = self.select_window = tk.Toplevel(self.root)
sw.wait_visibility(self.root)
sw.withdraw()
sw.config(bg='#00aaff')
sw.overrideredirect(True)
sw.wm_attributes('-alpha', 0.3)
sw.wm_attributes("-topmost", True)
self.font = tkfont.nametofont('TkTextFont')
self.style = parent.style
self.linespace = self.font.metrics('linespace') + 5
self.bind('<Escape>', self.tags_reset)
self.bind('<Button-1>', self.button_press)
self.bind('<ButtonRelease-1>', self.button_release)
def fixed_map(self, option):
return [elm for elm in self.style.map("Treeview", query_opt=option) if elm[:2] != ("!disabled", "!selected")]
def tag_add(self, tags, item):
self.tags_update('add', tags, item)
def tag_remove(self, tags, item=None):
self.tags_update('remove', tags, item)
def tag_replace(self, old, new, item=None):
for item in (item,) if item else self.tag_has(old):
self.tags_update('add', new, item)
self.tags_update('remove', old, item)
def tags_reset(self, _=None):
self.tag_remove(('selected', '_selected'))
self.tag_replace('selected_odd', 'odd')
self.tag_replace('selected_even', 'even')
def tags_update(self, opt, tags, item):
def get_items(node):
items.append(node)
for node in self.get_children(node):
get_items(node)
if not tags:
return
elif isinstance(tags, str):
tags = (tags,)
if not item:
items = []
for child in self.get_children():
get_items(child)
else:
items = (item,)
for item in items:
_tags = list(self.item(item, 'tags'))
for _tag in tags:
if opt == 'add':
if _tag not in _tags:
_tags.append(_tag)
elif opt == 'remove':
if _tag in _tags:
_tags.pop(_tags.index(_tag))
self.item(item, tags=_tags)
def button_press(self, event):
self.origin_x, self.origin_y = event.x, event.y
item = self.origin_item = self.active_item = self.identify('item', event.x, event.y)
sw = self.select_window
sw.geometry('0x0+0+0')
sw.deiconify()
self.bind('<Motion>', self.set_selected)
if not item:
if not event.state & 1 << 2:
self.tags_reset()
return
if event.state & 1 << 2:
if self.tag_has('odd', item):
self.tag_add('selected', item)
self.tag_replace('odd', 'selected_odd', item)
elif self.tag_has('even', item):
self.tag_add('selected', item)
self.tag_replace('even', 'selected_even', item)
elif self.tag_has('selected_odd', item):
self.tag_replace('selected_odd', 'odd', item)
elif self.tag_has('selected_even', item):
self.tag_replace('selected_even', 'even', item)
else:
self.tags_reset()
self.tag_add('selected', item)
if self.tag_has('odd', item):
self.tag_replace('odd', 'selected_odd', item)
elif self.tag_has('even', item):
self.tag_replace('even', 'selected_even', item)
def button_release(self, _):
self.select_window.withdraw()
self.unbind('<Motion>')
for item in self.selected_items:
if self.tag_has('odd', item) or self.tag_has('even', item):
self.tag_remove(('selected', '_selected'), item)
else:
self.tag_replace('_selected', 'selected', item)
def get_selected(self):
return sorted(self.tag_has('selected_odd') + self.tag_has('selected_even'))
def set_selected(self, event):
def selected_items():
items = []
window_y = int(self.root.geometry().rsplit('+', 1)[-1])
titlebar_height = self.root.winfo_rooty() - window_y
sw = self.select_window
start = sw.winfo_rooty() - titlebar_height - window_y
end = start + sw.winfo_height()
while start < end:
start += 1
node = self.identify('item', event.x, start)
if not node or node in items:
continue
items.append(node)
return sorted(items)
def set_row_colors():
items = self.selected_items = selected_items()
for item in items:
if self.tag_has('selected', item):
if item == self.origin_item:
continue
if self.tag_has('selected_odd', item):
self.tag_replace('selected_odd', 'odd', item)
elif self.tag_has('selected_even', item):
self.tag_replace('selected_even', 'even', item)
elif self.tag_has('odd', item):
self.tag_replace('odd', 'selected_odd', item)
elif self.tag_has('even', item):
self.tag_replace('even', 'selected_even', item)
self.tag_add('_selected', item)
for item in self.tag_has('_selected'):
if item not in items:
self.tag_remove('_selected', item)
if self.tag_has('odd', item):
self.tag_replace('odd', 'selected_odd', item)
elif self.tag_has('even', item):
self.tag_replace('even', 'selected_even', item)
elif self.tag_has('selected_odd', item):
self.tag_replace('selected_odd', 'odd', item)
elif self.tag_has('selected_even', item):
self.tag_replace('selected_even', 'even', item)
root_x = self.root.winfo_rootx()
if event.x < self.origin_x:
width = self.origin_x - event.x
coord_x = root_x + event.x
else:
width = event.x - self.origin_x
coord_x = root_x + self.origin_x
if coord_x+width > root_x+self.winfo_width():
width -= (coord_x+width)-(root_x+self.winfo_width())
elif self.winfo_pointerx() < root_x:
width -= (root_x - self.winfo_pointerx())
coord_x = root_x
root_y = self.winfo_rooty()
if event.y < self.origin_y:
height = self.origin_y - event.y
coord_y = root_y + event.y
else:
height = event.y - self.origin_y
coord_y = root_y + self.origin_y
if coord_y+height > root_y+self.winfo_height():
height -= (coord_y+height)-(root_y+self.winfo_height())
elif self.winfo_pointery() < root_y + self.linespace:
height -= (root_y - self.winfo_pointery() + self.linespace)
coord_y = root_y + self.linespace
if height < 0:
height = self.winfo_rooty() + self.origin_y
set_row_colors()
self.select_window.geometry(f'{width}x{height}+{coord_x}+{coord_y}')
class App(tk.Tk):
def __init__(self):
super().__init__()
def print_selected_items(_):
print(tv.get_selected())
return 'break'
style = self.style = ttk.Style()
tv = Treeview(self)
style.map("Treeview", foreground=tv.fixed_map("foreground"), background=tv.fixed_map("background"))
tv.heading('#0', text='Name')
tv.tag_configure('odd', background='#ffffff')
tv.tag_configure('even', background='#aaaaaa')
tv.tag_configure('selected_odd', background='#b0eab2')
tv.tag_configure('selected_even', background='#25a625')
color_tag = 'odd'
for idx in range(0, 4):
# Populating the tree with test data.
color_tag = 'even' if color_tag == 'odd' else 'odd'
tv.insert('', idx, f'{idx}', text=f'Item {idx+1}', open=1, tags=(color_tag,))
color_tag = 'even' if color_tag == 'odd' else 'odd'
iid = f'{idx}_{0}'
tv.insert(f'{idx}', '0', iid, text=f'Menu {idx+1}', open=1, tags=(color_tag,))
for i in range(0, 5):
color_tag = 'even' if color_tag == 'odd' else 'odd'
tv.insert(iid, i, f'{iid}_{i}', text=f'Sub item {i+1}', tags=(color_tag,))
color_tag = 'even' if color_tag == 'odd' else 'odd'
tv.insert(iid, 5, f'{iid}_{5}', text=f'Another Menu {idx+1}', open=1, tags=(color_tag,))
iid = f'{iid}_{5}'
for i in range(0, 3):
color_tag = 'even' if color_tag == 'odd' else 'odd'
tv.insert(iid, i, f'{iid}_{i}', text=f'Sub item {i+1}', tags=(color_tag,))
self.title('Treeview Demo')
self.geometry('275x650+3000+250')
self.rowconfigure(0, weight=1)
self.columnconfigure(0, weight=1)
tv.config(selectmode="none")
tv.grid(sticky='NSEW')
button = ttk.Button(self, text='Get Selected Items')
button.grid()
button.bind('<Button-1>', print_selected_items)
def main():
app = App()
app.mainloop()
if __name__ == '__main__':
main()
关于python - Tkinter Treeview 如何用鼠标正确选择多个项目,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61350804/
是否有某种方法可以使用 JPA 或 Hibernate Crtiteria API 来表示这种 SQL?或者我应该将其作为 native 执行吗? SELECT A.X FROM (SELECT X,
在查询中, select id,name,feature,marks from (....) 我想删除其 id 在另一个 select 语句中存在的那些。 从 (...) 中选择 id 我是 sql
我想响应用户在 select 元素中选择一个项目。然而这个 jQuery: $('#platypusDropDown').select(function () { alert('You sel
这个问题在这里已经有了答案: SQL select only rows with max value on a column [duplicate] (27 个回答) 关闭8年前。 我正在学习 SQL
This question already has answers here: “Notice: Undefined variable”, “Notice: Undefined index”, and
我在 php 脚本中调用 SQL。有时“DE”中没有值,如果是这种情况我想从“EN”中获取值 应该是这样的,但不是这样的 IF (EXISTS (SELECT epf_application_deta
这可能是一个奇怪的问题,但不知道如何研究它。执行以下查询时: SELECT Foo.col1, Foo.col2, Foo.col3 FROM Foo INNER JOIN Bar ON
如何在使用 Camera.DestinationType.FILE_URI. 时在 phonegap camera API 中同时选择或拾取多个图像我能够一次只选择一张图像。我可以使用 this 在
这是一个纯粹的学术问题。这两个陈述实际上是否相同? IF EXISTS (SELECT TOP 1 1 FROM Table1) SELECT 1 ELSE SELECT 0 相对 IF EXIS
我使用 JSoup 来解析 HTML 响应。我有多个 Div 标签。我必须根据 ID 选择 Div 标签。 我的伪代码是这样的 Document divTag = Jsoup.connect(link
我正在处理一个具有多个选择框的表单。当用户从 selectbox1 中选择一个选项时,我需要 selectbox2 active 的另一个值。同样,当他选择 selectbox2 的另一个值时,我需要
Acme Inc. Christa Woods Charlotte Freeman Jeffrey Walton Ella Hubbard Se
我有一个login.html其中form定义如下: First Initial Plus Last Name : 我的do_authorize如下: "; pri
$.get( 'http://www.ufilme.ro/api/load/maron_online/470', function(data
我有一个下拉列表“磅”、“克”、“千克”和“盎司”。我想要这样一种情况,当我选择 gram 来执行一个函数时,当我在输入字段中输入一个值时,当我选择 pounds 时,我想要另一个函数来执行时我在输入
我有一个 GLSL 着色器,它从输入纹理的 channel 之一(例如 R)读取,然后写入输出纹理中的同一 channel 。该 channel 必须由用户选择。 我现在能想到的就是使用一个 int
我想根据下拉列表中的选定值生成输入文本框。 Options 2 3 4 5 就在这个选择框之后,一些输入字段应该按照选定的数字出现。 最佳答案 我建议您使用响应式(Reac
我是 SQL 新手,我想问一下如何根据首选项和分组选择条目。 +----------+----------+------+ | ENTRY_ID | ROUTE_ID | TYPE | +------
我有以下表结构: CREATE TABLE [dbo].[UTS_USERCLIENT_MAPPING_USER_LIST] ( [MAPPING_ID] [int] IDENTITY(1,1
我在移除不必要的床单时遇到了问题。我查看了不同的论坛并将不同的解决方案混合在一起。 此宏删除工作表(第一张工作表除外)。 Sub wrong() Dim sht As Object Applicati
我是一名优秀的程序员,十分优秀!