Уведомления

Группа в Telegram: @pythonsu

#1 Май 7, 2013 23:46:38

vanvanov
Зарегистрирован: 2013-03-31
Сообщения: 252
Репутация: +  4  -
Профиль   Отправить e-mail  

Копирование текста в буфер

Python 3.3.0. Для копирования в буфер использую pyperclip. На Linux все копируется в порядке, а на WinXP выходят либо ошибки, либо белиберда.
pyperclip.copy(text) дает ошибку:

Traceback (most recent call last):
File “C:\Documents and Settings\limited\pyperclip.py”, line 61, in winSetClipb
oard
hCd = ctypes.windll.kernel32.GlobalAlloc(GMEM_DDESHARE, len(bytes(text))+1)
TypeError: string argument without an encoding

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File “tst.py”, line 6, in <module>
pyperclip.copy(text)
File “C:\Documents and Settings\limited\pyperclip.py”, line 64, in winSetClipb
oard
hCd = ctypes.windll.kernel32.GlobalAlloc(GMEM_DDESHARE, len(bytes(text, ‘asc
ii’))+1)
UnicodeEncodeError: ‘ascii’ codec can't encode characters in position 0-2: ordin
al not in range(128)
pyperclip.copy(text.encode('windows-1251','ignore')) выдает
Hello! Ïðèâåò!
Строка может указываться как напрямую в .py, так и вводиться через tkinter - с одинаковым результатом.

P.S. Декодировщик говорит, что необходимо CP1252 → CP1251, но не понятно, почему cp1252, если я прямо указываю cp1251. print(locale.getpreferredencoding()) также выдает cp1251.

Отредактировано vanvanov (Май 7, 2013 23:56:50)

Офлайн

#2 Май 8, 2013 11:17:26

4kpt
От: Харьков
Зарегистрирован: 2010-11-03
Сообщения: 998
Репутация: +  63  -
Профиль   Отправить e-mail  

Копирование текста в буфер

Не знаю как в тройке, но может подойдет это:

#Добавить в буфер обмена
import tkinter
tk = tkinter.Tk()
tk.withdraw()
tk.clipboard_clear() #Не отображать окно
tk.clipboard_append('This is clipboard contents.')
tk.destroy()
#А извлечь из буфера обмена
cb = tk.selection_get(selection = "CLIPBOARD")
Есть еще вот такой вариант
import win32clipboard
from datetime import date
curDate = date.today().strftime("%d.%m.%Y")
win32clipboard.OpenClipboard()
win32clipboard.EmptyClipboard()
win32clipboard.SetClipboardText(curDate)
win32clipboard.CloseClipboard()
P.S. Кстати, не знаю где этот код взял. На работоспособность проверял только первый, посему дерзайте :)



Отредактировано 4kpt (Май 8, 2013 11:20:57)

Офлайн

#3 Май 8, 2013 17:02:22

vanvanov
Зарегистрирован: 2013-03-31
Сообщения: 252
Репутация: +  4  -
Профиль   Отправить e-mail  

Копирование текста в буфер

4kpt, проверил 2-й вариант, заметил следующее:
1) Через поле tkinter работает корректно (для получения текста использую entry.get(), потом полученный текст копируется в буфер) (Хотя один раз, кажется, все равно выдал белиберду по непонятной причине)
2) Из текстового файла копирует белиберду (брал разные кодировки - CP1251,UTF-8, но безрезультатно). Декодер показывает, что все равно текст предварительно сконвертирован в CP1252.
Ничего не понимаю.

P.S. Заметил еще большую странность. Кодировка нормально работает после вызова tkinter. Т.е., например,

#!/usr/bin/python3
import win32clipboard
from tkinter import *
default_line_break='\n'
file="orig claims - ru"
with open(file) as f:
	text=f.read()
win32clipboard.OpenClipboard()
win32clipboard.EmptyClipboard()
win32clipboard.SetClipboardText(text)
win32clipboard.CloseClipboard()
не работает, а
#!/usr/bin/python3
import win32clipboard
from tkinter import *
default_line_break='\n'
def text_field(title):
	root, res = Tk(), [None]
	# Обратить внимание, что get() работает по-разному для Text и Entry 
	def callback(): res[0] = entry.get(1.0,END); root.destroy()
	root.title(title)
	scrollbar = Scrollbar(root,jump=0)
	# Маленькое окно: entry=Text(root,width=40,height=15,font="14")
	entry=Text(root,font="14",wrap=WORD,yscrollcommand=scrollbar.set)
	# Позволяет использовать мышь для управления скроллбаром
	scrollbar.config(command=entry.yview)
	scrollbar.pack(side=RIGHT,fill=Y)
	entry.pack()
	# Выход по нажатию Enter
	entry.bind('<Return>', lambda e: callback())
	# Выход по клику кнопки
	ok = Button(root, text='Ввести и выйти',command=callback)
	ok.pack()
	# Выход по нажатию Enter и Пробел на кнопке (навигация по Shift+Tab)
	ok.bind('<Return>', lambda e:callback())
	entry.focus_set()
	root.mainloop()
	if str(res[0])=='None' or str(res[0])==default_line_break:
		ErrorMessage(empty_field_error_msg)
		sys.exit()
	return res[0]
text=text_field('Введите любой текст:')
win32clipboard.OpenClipboard()
win32clipboard.EmptyClipboard()
win32clipboard.SetClipboardText(text)
win32clipboard.CloseClipboard()
file="orig claims - ru"
with open(file) as f:
	text=f.read()
win32clipboard.OpenClipboard()
win32clipboard.EmptyClipboard()
win32clipboard.SetClipboardText(text)
win32clipboard.CloseClipboard()
работает, но почему?

Отредактировано vanvanov (Май 8, 2013 17:18:42)

Офлайн

#4 Май 8, 2013 18:18:17

4kpt
От: Харьков
Зарегистрирован: 2010-11-03
Сообщения: 998
Репутация: +  63  -
Профиль   Отправить e-mail  

Копирование текста в буфер

Простите, но у меня верхний скрипт работате нормально.

import win32clipboard
file="README.txt"
with open(file) as f:
	text=f.read()
win32clipboard.OpenClipboard()
win32clipboard.EmptyClipboard()
win32clipboard.SetClipboardText(text)
win32clipboard.CloseClipboard()
Все уходит в буфер обмена как надо.
Скорее всего у Вас проблема с открытием файла в нужной кодировке…



Офлайн

#5 Май 11, 2013 10:53:23

vanvanov
Зарегистрирован: 2013-03-31
Сообщения: 252
Репутация: +  4  -
Профиль   Отправить e-mail  

Копирование текста в буфер

4kpt, проверял на XP, 2003, 7 - неверная кодировка. Какой у вас язык в системе? Какая версия?

Офлайн

#6 Май 11, 2013 14:34:39

4kpt
От: Харьков
Зарегистрирован: 2010-11-03
Сообщения: 998
Репутация: +  63  -
Профиль   Отправить e-mail  

Копирование текста в буфер

Еще раз. Пролистайте форум. Много раз уже говорили об открытии файлов с разными кодировками…
Я брал обычный файл внутри питонячей папки. У меня 2.Х и ХР. Тройкой не пользуюсь.

P.S. Полистал за Вас. По-моему Вам нужно это :)
http://www.python.su/forum/topic/21221/



Отредактировано 4kpt (Май 11, 2013 14:38:00)

Офлайн

#7 Фев. 25, 2014 13:41:25

vanvanov
Зарегистрирован: 2013-03-31
Сообщения: 252
Репутация: +  4  -
Профиль   Отправить e-mail  

Копирование текста в буфер

4kpt
Простите, но у меня верхний скрипт работате нормально.
Нашел проблему. Как оказалась, в винде буфер обмена зависит от раскладки по умолчанию (!!). Если скопировать файл, даже открыв его с указанием правильной кодировки (open(file,encoding='utf-8')), то все равно на выходе можно получить мусор, если раскладка по умолчанию - английская (как у меня). Поэтому делать это надо так:

# Задать раскладку клавиатуры (временно)
def set_keyboard_layout(lang): #str
	if lang=='ru':
		layout_index='00000419'
	elif lang=='en':
		layout_index='00000409'
	else:
		ErrorMessage('Внутренняя ошибка. Неверный идентификатор раскладки.')
	try:
		win32api.LoadKeyboardLayout(layout_index,1)
	except:
		Warning('Не удается изменить раскладку клавиатуры. Поскольку в ОС Windows это влияет на буфер обмена, то вы получите неверную кодировку.')
# Скопировать в буфер обмена
def buffer_copy(line):
	if sys_type=='win':
		set_keyboard_layout('ru')
		# Строка должна быть в UTF-8. Если идет чтение из файла, то это надо делать как open(file,encoding='utf-8')
		win32clipboard.OpenClipboard()
		win32clipboard.EmptyClipboard()
		win32clipboard.SetClipboardText(line)
		win32clipboard.CloseClipboard()
		set_keyboard_layout('en')
	else:
		pyperclip.copy(line)

Отредактировано vanvanov (Фев. 25, 2014 13:41:55)

Офлайн

#8 Май 7, 2014 03:01:51

vanvanov
Зарегистрирован: 2013-03-31
Сообщения: 252
Репутация: +  4  -
Профиль   Отправить e-mail  

Копирование текста в буфер

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version