Clipboard, автоматизация.

Vlad69

Новичок
Пользователь
Мар 17, 2021
6
0
1
Здравствуйте. Раньше я пользовался переводчиком Dicter. Он был очень востребован, когда осваивал python & visual code в прошлом году, когда "ушли" в самоизоляцию. Теперь, когда перевод стал платным у яндекса, пришлось сооружать что-то своё. И оно работает. Но мне интересно, как в Dicter реализована автоматизация. Выделение строки для перевода -> нажатие горячих клавиш ctrl+alt -> происходит вставка текста в окно программы dicter и сразу перевод. Когда проверяешь буфер обмена после ctrl+alt, например вставляя в блокнот содержимое буфера, то ничего нету. Такое впечатление, что всё происходит мимо буфера, либо очень хитрым способом. Есть ли тут, кто может показать направление, наверняка в питоне это возможно. Но я столько времени потратил на подобное, но ничего не нашёл даже близко. Когда мы делаем что-то, что связано с ctrl+с - это действует глобально. Но вот в dicter это реализовано очень индивидуально - работает только для данной программки. Вы меня понимаете? Как этого можно достичь в python? Пытался использовать block_key и remap_hotkey и pyperclip... все они имеют глобальное влияние, то есть они имели влияние на сторонние программы, будь-то блокнот или что-то другое. Более того, их применение не исключало параллельное использование ctrl+c. В dicter это сделано изящно. Попробуйте сами. Такая изящность пайтону возможна? Стоит ли продолжать поиски? Кстати, когда вводишь ctrl+alt после очередного копирования, видно, что dicter обновляется - исчезает и быстро появляется вновь с новым содержимым. Ну как-то так.
 

regnor

Модератор
Команда форума
Модератор
Июл 7, 2020
2 642
472
83
а чем гугл переводчик плох? на мой взгляд он самый лучший по переводу технической документации...

нажатие горячих клавиш ctrl+alt
при нажатии этих клавиш выполняется функция которая вставляет текст и переводит, через тот же pyperclip это можно сделать...
Такое впечатление, что всё происходит мимо буфера
его можно чистить...
Выделение строки для перевода
как он понимает что вы выделили из других приложений и копирует, вот тут сразу не скажу, сам такого не делал...
как вариант, можно, к примеру, ожидать нажатия ctrl+c и вытаскивать текст уже из буфера и работать с ним...
еще как вариант, можно по нажатии тех же ctrl+alt вызывать системный буфер, который работает через ctrl+c, копировать туда текст, вставлять в свою программу, и очищать его, это можно реализовать, например, через winapi...
Такая изящность пайтону возможна
возможна...
Стоит ли продолжать поиски
смотря что вы ищите... готовое решение вряд ли найдете...
 

Vlad69

Новичок
Пользователь
Мар 17, 2021
6
0
1
я не говорю, что переводчик гугл плох. Просто выбрал яндекс, дело вкуса.
как он понимает что вы выделили из других приложений и копирует, вот тут сразу не скажу, сам такого не делал...
он делает это через ctrl+c, которая маскируется под ctrl+alt. Мой переводчик всплывает из свёрнутого состояния по нажатии ctrl+c. Когда я нажал ctrl+alt dicter, мой всплыл параллельно с ним. НО! Попробуйте что-то сделать сами типа заменить ctrl+с другой горячей клавишей с помощью модуля keyboard, то все эти изменения будут влиять и на другие программы. А dicter в этом плане выглядит как автономный, такая "прелесть" мне пока не даётся.
 

regnor

Модератор
Команда форума
Модератор
Июл 7, 2020
2 642
472
83
я не говорю, что переводчик гугл плох. Просто выбрал яндекс, дело вкуса.

он делает это через ctrl+c, которая маскируется под ctrl+alt. Мой переводчик всплывает из свёрнутого состояния по нажатии ctrl+c. Когда я нажал ctrl+alt dicter, мой всплыл параллельно с ним. НО! Попробуйте что-то сделать сами типа заменить ctrl+с другой горячей клавишей
я вам уже ответил, что это делается через winapi...
вы ищете готовых решений... их к сожалению нет...
на выходных скину пример, если будет время, щас нет настроения заниматься этим...
 
Последнее редактирование:

Vlad69

Новичок
Пользователь
Мар 17, 2021
6
0
1
мда, ну почему же нет решений (не вчера мир появился), есть вот - Симуляция нажатия клавиш клавиатуры на python | Заметки, идеи и скрипты (zabaykin.ru)

правда я заманался с этим. Как ни подстраивайся - автомат калашникова выходит - выстрел в ногу. Там что интересно, так это:
def openItNow(hwnd, windowText):
if windowText in win32gui.GetWindowText(hwnd):
win32gui.SetForegroundWindow(hwnd)
а потом всё, геморрой, мать. Ничего толкового не получается. Просто не хватает личного опыта.
 

regnor

Модератор
Команда форума
Модератор
Июл 7, 2020
2 642
472
83
def openItNow(hwnd, windowText):
if windowText in win32gui.GetWindowText(hwnd):
win32gui.SetForegroundWindow(hwnd)
это и есть winapi, если вы не заметили...

мда, ну почему же нет решений
вы же не нашли, где то почему то возникает гемморой...

а потом всё, геморрой, мать
возможно почитать документацию winapi? вообще winapi написано на си, там немного другой подход...

и в ссылке которую вы дали там окно активное должно быть, но с помощью небольших манипуляций это можно реализовать и в не активном окне, даже в свернутом, так как у каждого окна в винде есть интерфейсы ввода и вывода, и к нему можно обратиться напрямую, а не так как в примере по вашей ссылке...

как я понимаю, не приятно будет, что после каждого нажатия у вас будет выскакивать окно с переводом (именно выскакивать и перехватывать фокус!)...

вообще вы взялись за далеко не тривиальную задачу, если учите и частично знаете уже на данный момент только питон...
 
Последнее редактирование:

Vlad69

Новичок
Пользователь
Мар 17, 2021
6
0
1
видно, люблю трудности на свою голову. Просто обожаю их. Насчёт этого:
но с помощью небольших манипуляций это можно реализовать и в не активном окне, даже в свернутом
это делается запросто:
QApplication.clipboard().dataChanged.connect...
автоматический перехват содержимого буфера без активации окна. Просто ловушка буфера. Но в таком неактивном окне keyPressEvent: if e.key() == Qt.Key_Escape or e.key() == Qt.Key_F8
не работают, работает только что-то глобальное, типа keyboard.add_hotkey('F8'...). Но он в свою очередь вызывает конфликт потоков при отладке в отличие от keyPressEvent, который совершенно бесконфликтен. Я так понимаю, пайтон - это простота решений. Если нет простого решения, тогда переходим к геморрою.
как я понимаю, не приятно будет, что после каждого нажатия у вас будет выскакивать окно с переводом
у dicter эта проблема с выскакиванием и сразу с переводом обеспечивается с помощью некоего рендера. Окно обновляется на глазах без лишних телодвижений. Я это заметил, в том числе наблюдая processmonitor. Это нужно для обновления окна. Покажите мне простой способ активации окна по изменению буфера. Активации окна, в которое вставляется содержимое буфера. Самый простой способ активации окна - это свёртывание и развёртывание. Ну попробуйте у себя self.showMinimized. Когда ctrl+с -> окно разворачивается и становится активным. Каждое копирование в буфер у dicter сопровождается апдейтом окна ради активации. А так да, QApplication.clipboard().dataChanged и дело в шляпе, но окно остаётся неактивным, а значит дальнейшие внутренние манипуляции невозможны, кроме глобальных "приёмов", типа keyboard или shell.SendKeys(...) или, возможно, tkinter.

-------
вне темы, когда набираете "self" кириллицей, то получаете "ыуда". Пайтон - удав. Что думает программистская братва по поводу того, что иуда удавился, повесившись? :)
 

regnor

Модератор
Команда форума
Модератор
Июл 7, 2020
2 642
472
83
это делается запросто:
QApplication.clipboard().dataChanged.connect...
я говорил именно про винапи...
и ожидание нажатия сочетаний клавиш в неактивном окне тоже можно описать на винапи, и скорее всего нигде не получится больше, по крайней мере я не знаю такого решения, и оно не будет ни на кого влиять, если только в стороннем приложении есть такая же комбинация и оно его тоже ждет...

язык пайтон назван в честь английской комик группы монти пайтон, так что аналогия немного не верна)

Покажите мне простой способ активации окна по изменению буфера
завтра на работе буду дежурить, скину на винапи
 

Vlad69

Новичок
Пользователь
Мар 17, 2021
6
0
1
скажите, пожалуйста, если известно, почему приложение exe (от пайтона) самозакрывается через четыре минуты простоя? что может означать строка:
"Путь сбойного модуля: C:\Users\Az\AppData\Local\Temp\_MEI67802\Qt5Core.dll"
Если запустить программку и ничего с ней не делать, то самозакрывается из-за ошибки переполнения стека:
Код исключения: 0xc0000409
Смещение ошибки: 0x00020071
я не программист, и не догоняю тему. Причём, самозакрывается отнюдь не всегда, а при каких-то ещё действиях, не связанных с этой программой.
Хотел попробовать что-то узнать через procdump, но, зараза, перестала ошибаться.
 

regnor

Модератор
Команда форума
Модератор
Июл 7, 2020
2 642
472
83
обычно переполнение стека возникает из за рекурсии из которой нет выхода...
так же может возникнуть из за утечки памяти, но в питоне это сделать довольно таки тяжело...

upd
и да я вам не скинул пример на вин апи так как вы ударились в qt, и сказали что вин апи слишком вас затруднил...
qt кстати на си++ написан, и там вполне возможно сделать переполнение или утечку, но повторюсь, в питоне это очень тяжело сделать...
 
Последнее редактирование:

Vlad69

Новичок
Пользователь
Мар 17, 2021
6
0
1
рекурсия, рекурсия... самовызывание, зеркальная перспектива. А что может вызывать такую "перспективу"? Есть
Python:
    def mousePressEvent(self, event):
        if event.button() == Qt.LeftButton:
            self.old_pos = event.pos()
есть:
Python:
    def initUI(self):
        self.setWindowFlags(self.windowFlags() ^
                            QtCore.Qt.WindowStaysOnTopHint)
есть:
Python:
class KeyboardManager(QObject):
    pasteSignal = pyqtSignal()
все три от QtCore, последний, class, вставлен перед родительским:
Python:
class MyWindow(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        QtWidgets.QWidget.__init__(self, parent)
скорей всего перец в этом, в последнем из трёх. Чё-то я не понимаю, почему всё-таки рекурсия?
 

regnor

Модератор
Команда форума
Модератор
Июл 7, 2020
2 642
472
83
скорей всего перец в этом
почему?

по этим отрывкам кода ничего непонятно...

можете воспользоваться дебагером, он вам скажет точно, где возникло переполнение стека...

так же вы не учитываете, что qt использует библиотеки от си++, и там вполне легко сделать переполнение стека через утечку памяти...

утечка памяти, к примеру, может вызывать функция которая в ожидании бесконечно создает объекты...

без полного кода я вам не помогу...

если код большой, то тоже быстро я вам не помогу, это надо разобраться в нем, указать ошибки, если они там есть по моему мнению...
 

regnor

Модератор
Команда форума
Модератор
Июл 7, 2020
2 642
472
83
рекурсия, рекурсия... самовызывание
рекурсия это не только самовызывание...
к примеру есть функция А, она вызывает функцию Б, она в свою очередь вызывает функцию В, а она вызывает функцию А...
это тоже рекурсия... при чем которую довольно сложно найти без дебагера...
и если из этой рекурсии нет выхода, то возникает ошибка переполнения стека... в си++ так... а так как qt это си++ - то возможно все...
 

regnor

Модератор
Команда форума
Модератор
Июл 7, 2020
2 642
472
83
я не смогу вам помочь, простите...
 

Форум IT Специалистов