gpt4 book ai didi

python - 如何使用 ctrl+c 和 ctrl+v 将文件夹从一个文件夹复制、剪切到另一个文件夹

转载 作者:行者123 更新时间:2023-12-04 00:48:59 24 4
gpt4 key购买 nike

我的标题可能看起来有点模棱两可,所以这里有一个解释。
专业的IDE,如PycharmVisual Studio Code允许复制文件夹,导航到特定目录并将其粘贴到那里。我也想实现这一点。
但就我而言,shutil.copytree needs 2 arguments - source folder and destination folder.
那么有什么方法可以复制文件夹,浏览资源管理器,单击粘贴或按ctrl+v并且文件夹将被复制或粘贴到那里,不像shutil.copytree用户已经需要在哪里提供路径?
目前,我有一个将文件夹名称复制到剪贴板的代码。

import os
import tkinter as tk
import tkinter.ttk as ttk
import clipboard
class App(tk.Frame):
def __init__(self, master, path):
tk.Frame.__init__(self, master)
self.tree = ttk.Treeview(self)
ysb = ttk.Scrollbar(self, orient='vertical', command=self.tree.yview)
xsb = ttk.Scrollbar(self, orient='horizontal', command=self.tree.xview)
self.tree.configure(yscroll=ysb.set, xscroll=xsb.set)
self.tree.heading('#0', text=path, anchor='w')

abspath = os.path.abspath(path)
root_node = self.tree.insert('', 'end', text=abspath, open=True)
self.process_directory(root_node, abspath)

self.tree.bind("<Control-c>",self.copy_to_clipboard)
self.tree.grid(row=0, column=0)
ysb.grid(row=0, column=1, sticky='ns')
xsb.grid(row=1, column=0, sticky='ew')
self.grid()
def copy_to_clipboard(self,event,*args):
item = self.tree.identify_row(event.y)
clipboard.copy(self.tree.item(item,"text"))
def process_directory(self, parent, path):
try:
for p in os.listdir(path):
abspath = os.path.join(path, p)
isdir = os.path.isdir(abspath)
oid = self.tree.insert(parent, 'end', text=p, open=False)
if isdir:
self.process_directory(oid, abspath)
except PermissionError:
pass

root = tk.Tk()
path_to_my_project = 'C:\\Users\\91996\\Documents'
app = App(root, path=path_to_my_project)
app.mainloop()

最佳答案

备注 :这个答案没有回答 OP 的问题,因为它可以从外部文件浏览器复制到 tkinter 应用程序中选择的文件夹中,但不是相反,正如 OP 所希望的那样。
首先,为了更容易检索项目的绝对路径,我使用绝对路径作为树中的项目标识符。
然后,为了实现粘贴部分,我添加了一个 .paste()方法,使用 Ctrl+V 调用。在这种方法中,我通过获取当前选中的项目来获取目标文件夹。如果这个项目是一个文件,那么我使用父文件夹作为目标。我得到要从剪贴板复制的文件/文件夹的路径。如果是文件,我用shutil.copy2(src, dest) .因为它会复制文件,即使它已经存在于 dest 中。 ,您可能需要在检查之前添加一些代码并显示一个消息框。如果源是文件夹,我使用 shutil.copytree(src, os.path.join(dest, src_dirname))在哪里 src_dirname是复制文件夹的名称。
正如评论中所建议的,我使用了 tkinter 的方法 .clipboard_clear() , .clipboard_append().clipboard_get()而不是使用 clipboard模块。
.copy_to_clipboard() , 建议你使用self.tree.focus()而不是 self.tree.identify_row(y) , 以便获取选中的项目,而不是鼠标光标下方的项目(我刚刚在代码中的相关行旁边添加了注释但没有实现这个建议)。
这是代码:

import os
import tkinter as tk
import tkinter.ttk as ttk
from tkinter.messagebox import showerror
import shutil
import traceback


class App(tk.Frame):
def __init__(self, master, path):
tk.Frame.__init__(self, master)
self.tree = ttk.Treeview(self)
ysb = ttk.Scrollbar(self, orient='vertical', command=self.tree.yview)
xsb = ttk.Scrollbar(self, orient='horizontal', command=self.tree.xview)
self.tree.configure(yscroll=ysb.set, xscroll=xsb.set)
self.tree.heading('#0', text=path, anchor='w')

abspath = os.path.abspath(path)
self.tree.insert('', 'end', abspath, text=abspath, open=True)
self.process_directory(abspath)

self.tree.bind("<Control-c>", self.copy_to_clipboard)
self.tree.bind("<Control-v>", self.paste)
self.tree.grid(row=0, column=0)
ysb.grid(row=0, column=1, sticky='ns')
xsb.grid(row=1, column=0, sticky='ew')
self.grid()

def copy_to_clipboard(self, event, *args):
item = self.tree.identify_row(event.y) # you may want to use self.tree.focus() instead so that
# the selected item is copied, not the one below the mouse cursor
self.clipboard_clear()
self.clipboard_append(item)

def paste(self, event):
src = self.clipboard_get()

if not os.path.exists(src):
return

dest = self.tree.focus()
if not dest:
dest = self.tree.get_children("")[0] # get root folder path
elif not os.path.isdir(dest): # selected item is a file, use parent folder
dest = self.tree.parent(dest)

if os.path.isdir(src):
try:
dirname = os.path.split(src)[1]
newpath = shutil.copytree(src, os.path.join(dest, dirname))
self.tree.insert(dest, "end", newpath, text=dirname)
self.process_directory(newpath)
self.tree.item(dest, open=True)
except Exception:
showerror("Error", traceback.format_exc())
else:
try:
# you might want to check if the file already exists in dest and ask what to do
# otherwise shutil.copy2() will replace it
newpath = shutil.copy2(src, dest)
self.tree.insert(dest, "end", newpath, text=os.path.split(src)[1])
except tk.TclError: # the item already exists
pass
except Exception:
showerror("Error", traceback.format_exc())

def process_directory(self, path):
try:
for p in os.listdir(path):
abspath = os.path.join(path, p)
isdir = os.path.isdir(abspath)
# use abspath as item IID
self.tree.insert(path, 'end', abspath, text=p, open=False)
if isdir:
self.process_directory(abspath)
except PermissionError:
pass

root = tk.Tk()
path_to_my_project = '/tmp/truc'
app = App(root, path=path_to_my_project)
app.mainloop()

从 tkinter 应用程序复制到外部文件浏览器的部分实现:在这个方向复制的问题在于它是特定于平台的,因为不同平台对剪贴板的处理方式不同。以下解决方案适用于 Linux , 在 XFCE 桌面环境和使用 图纳尔 文件浏览器。
我用了 klembord库来访问系统的剪贴板,内容比纯文本更丰富。如果已将文件/文件夹复制到剪贴板,则可以在 Thunar 中粘贴文件/文件夹
klembord.set({'x-special/gnome-copied-files': f'copy\nfile://{abspath}'.encode()})
在哪里 abspath是文件/文件夹的 HTML 转义绝对路径。
将其实现到 App , 进口 klembordurllib.parse并更换
self.clipboard_clear()
self.clipboard_append(item)
.copy_to_clipboard()经过
klembord.set({'x-special/gnome-copied-files': 
f'copy\nfile://{urllib.parse.quote(item)}'.encode()})

关于python - 如何使用 ctrl+c 和 ctrl+v 将文件夹从一个文件夹复制、剪切到另一个文件夹,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68164678/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com