LINUX.ORG.RU

Сообщения denton

 

Резервное копирование попадает в бесконечный цикл

Привет всем!

Долгое время пользовался rsync для резервного копирования системы и данных, и все было хорошо. Вышел новый минорный Дебиан, и я решил сделать бэкап системы (тем же самым скриптом, как и всегда).

На этот раз rsync перестает печатать строки после var/log/faillog, потом свободное место на внешнем диске, сколько бы его ни было, заканчивается.

Возникла мысль, что где-то, вероятно, образуются циклические ссылки, что я и проверил командой

find / -follow -printf ""
В результате выводится огромное число сообщений типа
find: Обнаружено зацикливание в файловой системе; ‘/sys/devices/pci0000:00/0000:00:1c.3/subsystem/devices/0000:00:1e.0/pci_bus/0000:11/subsystem/0000:09/device/driver/0000:00:1c.1/firmware_node/subsystem/devices/PNP0800:00/physical_node/subsystem/devices/PNP0C0E:00/firmware_node/driver/LNXPWRBN:00/input/input9/subsystem/event13/device/device/subsystem/devices/usb5/driver/4-1.1.4/4-1.1.4:1.0/host4/subsystem/devices/host1/scsi_host/host1/subsystem/host0/device/target0:0:0/0:0:0:0/block/sda/sda3/subsystem/sdb/subsystem’ является частью той же петли файловой системы что и ‘/sys/devices/pci0000:00/0000:00:1c.3/subsystem/devices/0000:00:1e.0/pci_bus/0000:11/subsystem/0000:09/device/driver/0000:00:1c.1/firmware_node/subsystem/devices/PNP0800:00/physical_node/subsystem/devices/PNP0C0E:00/firmware_node/driver/LNXPWRBN:00/input/input9/subsystem/event13/device/device/subsystem/devices/usb5/driver/4-1.1.4/4-1.1.4:1.0/host4/subsystem/devices/host1/scsi_host/host1/subsystem/host0/device/target0:0:0/0:0:0:0/block/sda/sda3/subsystem’

Удалил старый бэкап полностью и переписал команду (/dev/sda1 смонтирован на /mnt) как

rsync -av --exclude /mnt/mnt --exclude /tmp --exclude /sys/devices --delete /mnt/* /media/OLD/backup/devuan/
но это не помогло.

Как исправить ситуацию?

 , , ,

denton ()

Новогодний «подарок» от Ростелеком

За декабрь пришла квитанция в 685 руб вместо 600 (СПб). Само по себе недешево, так еще навязывают антивирус! Позвонил в поддержку, выяснилось, что так они делают для ВСЕХ абонентов в рамках «рекламной акции». Уведомление приходит по СМС (но лично я все СМС с незнакомых номеров блокирую). Типа месяц «услуга» бесплатна, потом начинают стричь. Единственный плюс - можно отключить автоподключение всех платных услуг в дальнейшем и сделать перерасчет. В общем, в лучших традициях Мегафона.

 ,

denton ()

Виснут иксы

Привет всем!

Система Linux devuan 4.9.0-8-686-pae #1 SMP Debian 4.9.130-2 (2018-10-27) i686 GNU/Linux. Видео - встроенная карточка intel на нетбуке Samsung N100.

Основная проблема у меня с этим дистрибутивом в том, что виснут иксы. По всей видимости, как-то связано с мультимедиа - раньше висло при проигрывании видео, а сегодня - музыки с внешнего HDD. Зависания рандомные, иногда - раз в неделю, а иногда - три раза на день. При зависании картинка остается статичной, курсор раньше, по-моему, вис, а сегодня исчез (Работаю с внешним монитором. Когда беру нетбук с собой, иногда пропадает курсор - может, это как-нибудь связано). На Ctrl-Alt-F1..7 не реагирует, но, что интересно, после зависания картинки звук продолжает работать! Вот только то, что программы, по-видимости, работают в фоне, не помогает, потому что спасает только жесткий рестарт. Вот лог Xorg, но не уверен, что он актуален, потому что ls -l показывает на нем ровно то время, когда пришлось сделать рестарт.

Как дебажить, куда копать?

 ,

denton ()

Сборка AppImage для программ на Python3

Привет всем!

Мне уже удавалось собирать код на Python3 с помощью cx-freeze или pyinstaller, но мне хотелось бы собрать AppImage для всех линуксовых дистрибутивов. Оставить в исходном коде - не совсем вариант. Запуск питона со всеми pip-зависимостями и (иногда) исправленными багами в site-packages для новичка нелегок будет. Заморачиваться с пакетированием под все основные системы не очень хочется, решил остановиться на AppImage.

Как я это делаю сейчас:

1) запускаю cx_freeze/pyinstaller, получаю каталог с бинарниками.

2) Создаю usr/bin, перемещаю бинарники в него

3) Копирую в текущий каталог AppRun (ELF), MyApp.desktop, MyApp.png.

4) Делаю

strace -eopen -f ./AppRun 2>&1 | grep / | grep -v ENOENT | cut -d "\"" -f 2 | sort | uniq > copyfiles
Это находит все используемые в системе файлы.

5) Удаляю из copyfiles то, что, скорее всего, копировать не нужно (/etc/passwd, /dev/null и т.д.).

6) Копирую в каталог с AppRun файлы из copyfiles, принимая текущий каталог за /. Т.е., /lib/somelib.so -> ./lib/somelib.so, /etc/fonts/somefont -> ./etc/fonts/somefont и т.д.

7) Для каталога с AppRun применяю appimagetool, он собирает AppImage.

Проблема в том, что такая сборка использует как локальные, так и системные файлы. Например, после запуска на другой ОС я получаю segmentation fault, но после удаления из ./lib libgc, libpthread и lipdl, программа запускается. Т.е., какие-то библиотеки из ./lib используются. Однако, не используются шрифты из ./etc/fonts - я получаю сообщения об ошибках (обращение, по всей видимости, по-прежнему идет к /etc/fonts), на некотых ОС я получаю квадраты.

Также проблема с сертификатами, получаю ошибку SSL: CERTIFICATE_VERIFY_FAILED. Иногда помогает установка ca_certificates, но на разных ОС сертификаты находятся в РАЗНЫХ каталогах! ЕМНИП, для centos - /etc/pki/tls, для debian - /etc/ssl/certs, для TinyCore - /usr/local/etc/ssl/certs. После создания /etc/pki/tls/cert.pem программа, собранная на centos, завелась на debian. Однако, ни сборка на centos, ни сборка на debian8 не завелась полностью на TinyCore - CERTIFICATE_VERIFY_FAILED и квадраты вместо кириллицы.

В общем, вопрос: как грамотно сделать сборку? Может, требуется пропатчить libpython в сборке (если там есть жесткая привязка к системным файлам)?

P.S. Я знаю про существование yml и TravisCI, но я пока не понял, что оно делает, какого рода скрипты можно вставить в yml и что вообще получается на выходе. Хочется пока руками, чтобы разобраться.

 ,

denton ()

Зависание системы

Привет всем! Сегодня прямо во время работы на ноутбуке получил панику ядра (мигал capslock). Консольного вывода не было, на экране просто остался GUI текущих приложений как он был. После перезагрузки сразу сделал dmesg, но я его плохо понимаю, к тому же, время там не указано. Система Centos 6, ядро 2.6.32-754.3.5.el6.i686. Поможете определить, в какой момент возникла паника и из-за чего? Вывод dmesg.

 ,

denton ()

Ethernet-адатер для подключения к смартфону?

На андроид-смартфоне нужен интернет для видеозвонков. Есть мобильный интернет, но хотелось бы что-нибудь потолще. Не хочется покупать WiFi-роутер при наличии только 1 комнаты. Что тут можно сделать? Я в плане оборудования особо не шарю, поэтому извините, если пытаюсь скрестить ужа и ежа. На данный момент алгоритм действий представляю себе следующим образом:

1) Есть проводной интернет (DOCSIS), который раздает модем Arris (установил Ростелеком). На этом модеме только 1 вход для RJ45. Поэтому сначала понадобится купить сплиттер для такого разъема (такие вообще бывают?).

2) Потом купить Ethernet-адаптер по типу такого. Некоторые из таких устройств требуют наличия драйверов, не знаю, зачем.

3) Взять переходник USB -> мини-USB и соединить со смартфоном.

Не знаю, сработает ли это, возможно, это бред. Ваш вариант действий?

 

denton ()

Вкладки как в elinks

Добрый вечер!

Мне очень нравится elinks, хочу сделать простой консольный браузер на Python3, только заточенный под себя. Не понимаю, как реализовать в консоли вкладки (tabs). Выглядят они так: https://i.imgur.com/5TcuGCF.jpg

Установил модуль clint, но из интересного для меня нашел там разве что отступы и цвета.

Может быть, подскажете, как это делается? Интересует, прежде всего, линуксовая консоль, но кроссплатформенные решения приветствуются!

 ,

denton ()

Новым руководителем проекта Linux станет Леннарт Поттеринг

Линус Торвальдс, бессменный руководитель проекта Linux и его ведущий разработчик на протяжении 27 лет, объявил о своем уходе из компании RedHat и прекращении деятельности по разработке ядра. «Я устал, пора передавать пальму первенства новому, прогрессивному поколению», сказал он.

Эстафетная палочка переходит другому известному сотруднику RedHat - Леннарту Поттерингу. Леннарт уже заявил об интеграции своих разработок, в частности, systemd, в ядро.

Бизнес-пользователи с воодушевлением восприняли должностные перестановки в RedHat. Лидеры крупнейших IT-компаний заявили о том, что ожидают унификацию и дефрагментацию платформы Linux в связи с грядущими изменениями. Директор Microsoft Russia и руководитель облачной платформы Azure рассказали о том, что компании Microsoft будет проще интегрировать свои решения в обновленную платформу Linux.

Инициативная группа разработчиков-альтруистов, не зависящая от компании RedHat, заявила о создании Librux, форка ядра Linux, поскольку не согласна с изменениями, предлагаемыми Леннартом Поттерингом.

Руководитель пресс-службы RedHat пока никак не прокомментировал вопрос журналистов о том, кому перейдут права на торговую марку Linux(TM) после ухода Торвальдса со своей должности.

P.S. Да, я знаю, что не смешно, КГ/АМ, но это, IMHO, вполне вероятное развитие событий. :(

 , , ,

denton ()

Обновление ядер и безопасность

Я использую CentOS 6 с ядром 2.6.32-696.3.2.el6.i686. Подскажите, пожалуйста, вносит ли команда

yum update --security
последние патчи безопасности в ядро, или же в данном дистрибутиве пропатчено только самое свежее ядро из реп.

 

denton ()

Я упоролся?

Как вам такой стиль оформления кода: https://pastebin.com/55vJAtdp

Да, это противоречит PEP, да еще и Mono-шрифт нужен, иначе разъезжается, но мне нравится :)

А вы что думаете?

 

denton ()

elinks еще жив?

Кто-нибудь знает, как обстоят дела с elinks? Последний стабильный релиз, насколько могу судить, состоялся 5 лет назад. На многие сайты перестал заходить - какая-то проблема с SSH. Даже при попытке зайти на википедию получаю «сеть недоступна».

Смотрел форки на github, вроде бы и есть какое-то движение, но все валятся с ошибкой

document.c:303: ошибка: слишком много аргументов в вызове функции ‘document_write_do’

Что мне хочется от текстового браузера:

1) (обязательно) должен быть быстрым (впрочем, сам elinks зачастую по несколько секунд страницу получает)

2) (обязательно) должен поддерживать вкладки

3) (желательно) настройка цвета

4) (опционально) поддержка графики, скриптов и пр. навороты

 

denton ()

Когда базы данных нужны, а когда нет?

Пытаюсь разобраться, в каких случаях БД нужны в десктопных приложениях, а в каких нет. Поможете подобрать use cases?

Конкретно интересует следующее (но не только). Нужно как-нибудь организовать данные в оболочке для словарей. А именно, организовать информацию о словарных статьях (источник, URL, заголовок, код в HTML, plain text и пр.) и об элементах статьи (тип, plain text, позиция и пр.). Хранить можно все в памяти (на данный момент). Элементы статьи должны быть привязаны к конкретной статье.

На данный момент все написано на Python 3, информация о статьях хранится в sqlite3, а элементы статьи реализованы классами. Хочется унифицировать.

Что нравится в БД - это мощь select, делается быстро и не нужно писать дополнительный код, понятная организация данных и контроль БД. Что не нравится - нужно вычислять все за раз и обновлять в транзакциях, иначе будут просадки по скорости.

 ,

denton ()

Фильтрация по тэгам не работает?

Я занес тэг «игры» в «Список игнорирования тегов» (правильнее было бы «Список игнорируемых тегов»), но все равно регулярно вижу игры на главной (их просто засилье). Чистил кэш, перезагружал страницу, перелогинивался. Не работает.

 ,

denton ()

Свернуть элементы в боковой панели

Добрый день. Не могу разобраться, как можно настроить Geany (1.24.1) так, чтобы при загрузке файла в боковой панели слева список классов не разворачивался вплоть до списка функций, мне нужно иметь только список классов. Сейчас оно выглядит так, а мне нужно так. Искал в google, yahoo и bing, но запрос «geany side panel folding» выдает мусор.

 

denton ()

update в цикле

Привет всем. В базах данных я новичок, поэтому всех подводных камней не знаю.

Нужно создавать таблицы примерно в 28 столбцов и 1500 строк или больше. БД нужна для хранения промежуточных вычислений анализа текста. Например, номер слова, само слово, слово в нижнем регистре, слово без пунктуации, формы склонения и т.д. При этом изначально база пустая, и ее надо пополнять не сразу, а в процессе обращения к требуемым элементам (не все элементы требуются, к тому же, экономятся ресурсы). Стало быть, для каждого элемента мне требуется выполнять update.

Почему операция update так долго выполняется, даже если БД создана в памяти? Почитал руководства, многократные update рекомендуется заворачивать в транзакции. У меня тестовая БД 7x1000 генерируется ~2.5 с. Это долго? Как оптимизировать? Пытался завернуть в транзакцию, прироста в производительности не наблюдаю. Пример кода ниже.

#!/usr/bin/python3

import sqlite3
from time import time

class SQLExample:
	
	def __init__(self):
		self._lst = []
	
	def lst(self):
		print('Building list...')
		if not self._lst:
			for i in range(1000):
				self._lst.append(i)
		return self._lst
	
	def create(self):
		self.db_con = sqlite3.connect(':memory:')
		self.db = self.db_con.cursor()
		self.db.execute('PRAGMA synchronous=OFF')
		self.db_con.isolation_level = 'DEFERRED'
		#self.db.execute('PRAGMA journal_mode=OFF')
		self.db.execute('create table WORDS (NO integer,P text,NP text,F_SYM_P integer,L_SYM_P integer,F_SYM_NP integer,L_SYM_NP integer)') # todo: commas before ')'?
		self.db_con.commit()
		
	def fill(self):
		for i in range(len(self.lst())):
			self.db.execute('insert into WORDS values (?,?,?,?,?,?,?)',(i,-1,-1,-1,-1,-1,-1,))
		self.db_con.commit()
		
	def close(self):
		self.db.close()
		
	def update(self):
		print('Updating DB...')
		start_time = time()
		for i in range(len(self.lst())):
			#print('Updating row #',i)
			self.db.execute('update WORDS set P=? where NO=?',(str(self._lst[i]),i,))
			self.db.execute('update WORDS set NP=? where NO=?',(str(self._lst[i]),i,))
			self.db.execute('update WORDS set F_SYM_NP=? where NO=?',(self._lst[i],i,))
			self.db.execute('update WORDS set L_SYM_NP=? where NO=?',(self._lst[i],i,))
			#self.db.executescript('begin; update WORDS set P=%s where NO=%d;update WORDS set NP=%s where NO=%d;update WORDS set F_SYM_NP=%s where NO=%d;update WORDS set L_SYM_NP=%s where NO=%s;commit;' % (str(self._lst[i]),i,str(self._lst[i]),i,str(self._lst[i]),i,str(self._lst[i]),i))
		self.db_con.commit()
		print('Finished in %s.' % str(time()-start_time))
		
	def run(self):
		print('Creating table...')
		self.create()
		print('Filling table...')
		self.fill()
		print('Updating table...')
		self.update()
		self.close()

SQLExample().run()

 ,

denton ()

Убрать меню «Недавние документы»

Привет всем. При использовании Geany или Gedit, когда нажимаю Ctrl-O, появляется вот такой диалог. По умолчанию выбран пункт «Недавние документы», который мне не нужен. Мне надо, чтобы по умолчанию выбирался последний использованный каталог или $HOME. Как это сделать? У меня Gnome/KDE только кусками, DE - Openbox.

 

denton ()

Обновления безопасности

Рабочая тачка, не сервер. Много раз обжегся на обновлениях, которые все ломали, в итоге перешел на CentOS, где они гибко настраиваются. С помощью yum-security устанавливаю только обновления безопасности. Прошу прощения, если вопрос нубский, но можно ли ограничиться такими обновлениями, или стоит устанавливать новое доступное ядро? Поддерживаются ли старые ядра? Что делать с SELinux (слышал, что ненастроенный файрвол хуже отсутствующего вообще)?

 ,

denton ()

Парсеры для словарей

Добрый день!

Посоветуйте, пожалуйста, программы и/или руководства, с помощью которых можно парсить и/или конвертировать словари в форматах GoldenDict / Stardict / Multitran / Lingvo и пр. (а также парсеры для онлайн-словарей).

Особенно интересуют парсеры для Python. Также очень хочется найти multitran-tool, но Google Code, на котором он хостился, умер, и зеркало найти не могу.

 , , , ,

denton ()

Tkinter + потоки

Известно, что Tkinter криво работает с потоками, поэтому интересует архитектура программы, в которой есть и то, и другое.

Конкретно проблема в следующем. Есть программа, в которой GUI сделан в Tkinter. Захотел, чтобы программа глобально отлавливала сочетание клавиш «Conrol-c-c», написал следующий модуль:

#!/usr/bin/python3

import sys
import signal
from Xlib.display import Display
from Xlib import X
from Xlib.ext import record
from Xlib.protocol import rq
import threading

globs = {'HotkeyCaught':False}

# todo: взять функции, вычисляющие keysym, из pyxhook
keysym_map = {32: "SPACE", 39: "'", 44: ",", 45: "-", 46: ".", 47: "/", 48: "0", 49: "1", 50: "2", 51: "3", 52: "4", 53: "5", 54: "6", 55: "7", 56: "8", 57: "9", 59: ";", 61: "=", 91: "[", 92: "\\", 93: "]", 96: "`", 97 :"a", 98 :"b", 99 :"c", 100: "d", 101: "e", 102: "f", 103: "g", 104: "h", 105: "i", 106: "j", 107: "k", 108: "l", 109: "m", 110: "n", 111: "o", 112: "p", 113: "q", 114: "r", 115: "s", 116: "t", 117: "u", 118: "v", 119: "w", 120: "x", 121: "y", 122: "z", 65293: "ENTER", 65307: "ESC", 65360: "HOME", 65361: "ARROW_LEFT", 65362: "ARROW_UP", 65363: "ARROW_RIGHT", 65505: "L_SHIFT", 65506: "R_SHIFT", 65507: "L_CTRL", 65508: "R_CTRL", 65513: "L_ALT", 65514: "R_ALT", 65515: "SUPER_KEY", 65288: "BACKSPACE", 65364: "ARROW_DOWN", 65365: "PG_UP", 65366: "PG_DOWN", 65367: "END", 65377: "PRTSCRN", 65535: "DELETE", 65383: "PRINT?", 65509: "CAPS_LOCK", 65289: "TAB", 65470: "F1", 65471: "F2", 65472: "F3", 65473: "F4", 65474: "F5", 65475: "F6", 65476: "F7", 65477: "F8", 65478: "F9", 65479: "F10", 65480: "F11", 65481: "F12"}

def catch_control_c(*args):
	pass
	
signal.signal(signal.SIGINT,catch_control_c) # do not quit when Control-c is pressed

def toggle_hotkey(SetBool=True):
	globs['HotkeyCaught'] = SetBool

# Определить нажатие горячих клавиш глобально в системе
class KeyListener(threading.Thread):
	''' Использование: 
		keylistener = KeyListener()
		keylistener.addKeyListener("L_CTRL+L_SHIFT+y", callable)
		Обратить внимание, что необходимо присвоить все возможные комбинации, поскольку порядок нажатия может быть иной, например, "L_CTRL+y+L_SHIFT"
	'''
	def __init__(self):
		threading.Thread.__init__(self)
		self.finished = threading.Event()
		self.contextEventMask = [X.KeyPress,X.MotionNotify]
		# Give these some initial values
		# Hook to our display.
		self.local_dpy = Display()
		self.record_dpy = Display()
		self.pressed = []
		self.listeners = {}
	#--------------------------------------------------------------------------
	def processevents(self, reply):
		if reply.category != record.FromServer:
			return
		if reply.client_swapped:
			print("* received swapped protocol data, cowardly ignored")
			return
		# Добавил str, иначе получаем ошибку
		if not len(str(reply.data)) or ord(str(reply.data[0])) < 2:
			# not an event
			return
		data = reply.data
		while len(data):
			event, data = rq.EventField(None).parse_binary_value(data, self.record_dpy.display, None, None)
			keycode = event.detail
			keysym = self.local_dpy.keycode_to_keysym(event.detail, 0)
			if keysym in keysym_map:
				character = keysym_to_character(keysym)
				if event.type == X.KeyPress:
					keylistener.press(character)
				elif event.type == X.KeyRelease:
					keylistener.release(character)
				#self.KeyUp(hookevent)
		#print "processing events...", event.type
	#--------------------------------------------------------------------------
	def run(self):
		# Check if the extension is present
		if not self.record_dpy.has_extension("RECORD"):
			print("RECORD extension not found")
			sys.exit(1)
		r = self.record_dpy.record_get_version(0, 0)
		print("RECORD extension version %d.%d" % (r.major_version, r.minor_version))
		# Create a recording context; we only want key events
		self.ctx = self.record_dpy.record_create_context(
				0,
				[record.AllClients],
				[{
						'core_requests': (0, 0),
						'core_replies': (0, 0),
						'ext_requests': (0, 0, 0, 0),
						'ext_replies': (0, 0, 0, 0),
						'delivered_events': (0, 0),
						'device_events': tuple(self.contextEventMask), #(X.KeyPress, X.ButtonPress),
						'errors': (0, 0),
						'client_started': False,
						'client_died': False,
				}])

		# Enable the context; this only returns after a call to record_disable_context,
		# while calling the callback function in the meantime
		self.record_dpy.record_enable_context(self.ctx, self.processevents)
		# Finally free the context
		self.record_dpy.record_free_context(self.ctx)
		#print('Starting hotkey watch (thread).')
	#--------------------------------------------------------------------------
	def cancel(self):
		self.finished.set()
		self.local_dpy.record_disable_context(self.ctx)
		self.local_dpy.flush()
		#print('Ending hotkey watch (thread).')
	#--------------------------------------------------------------------------
	def press(self, character):
		if len(self.pressed) == 3:
			self.pressed = []
		if character == 'L_CTRL' or character == 'R_CTRL':
			if len(self.pressed) > 0:
				self.pressed = []
			self.pressed.append(character)
		elif character == 'c':
			if len(self.pressed) > 0:
				if self.pressed[0] == 'L_CTRL' or self.pressed[0] == 'R_CTRL':
					self.pressed.append(character)
		action = self.listeners.get(tuple(self.pressed), False)
		#print('Current action:', str(tuple(self.pressed)))
		if action:
			action()
	#--------------------------------------------------------------------------
	def release(self, character):
		"""must be called whenever a key release event has occurred."""
		# Не засчитывает отпущенный Control
		# Кириллическую 'с' распознает как латинскую
		if character != 'c':
			self.pressed = []
	#--------------------------------------------------------------------------
	def addKeyListener(self, hotkeys, callable):
		keys = tuple(hotkeys.split("+"))
		print("Added new keylistener for :",str(keys))
		self.listeners[keys] = callable
	#--------------------------------------------------------------------------
	def result(self):
		if globs['HotkeyCaught']:
			print('Control-c-c detected!')
			globs['HotkeyCaught'] = False
			return True
		else:
			return False
		
keylistener = KeyListener()
keylistener.addKeyListener("L_CTRL+c+c",toggle_hotkey)
		
# Определить название клавиши по ее коду
# Переменная keysym_map должна быть глобальной
def keysym_to_character(sym):
	if sym in keysym_map:
		return keysym_map[sym]
	else:
		return sym
		
def wait_example():
	from time import sleep
	keylistener.start()
	while not keylistener.result():
		sleep(.5)
	keylistener.cancel()

if __name__ == '__main__':
	wait_example()

Модуль рабочий, осталось его только привязать к главной программе. Сейчас это сделано примерно так:

# Инициализируется tkinter, назначаются переменные и пр.
root = tk.Tk()
# Загружается модуль с кейлоггером, приведенный выше
kl_mod.keylistener.start()
# ... Здесь скачиваются и подготавливаются данные
# ... Здесь инициализируется класс, отображающий GUI на основе подготовленных данных
root.mainloop()
У класса есть спец. режим, в котором программа ждет, пока не будет нажато Control-c-c:
def wait_hotkey():
	while True:
		sleep(0.5)
		if kl_mod.keylistener.result():
			print('YES, we got it!')
			break
		else:
			print('No, still nothing...')
Пользователь нажимает кнопку в главной программе, программа входит в режиме ожидания. При нажатии Control-c-c происходит выход из цикла, на основе содержимого буфера обмена подготавливаются новые данные и происходит их отображение.

Итак, проблема в следующем. Как грамотно построить программу? Можно ли избавиться от необходимости нажимать кнопку, чтобы задействовать спец. режим ожидания, в процессе которого основная программа блокируется? Я хочу, чтобы Control-c-c сразу подхватывалось и основная программа продолжала работу без блокировки.

 , , ,

denton ()

Навигация по QTextEdit/QTextBrowser

Продолжаю изучение PyQt. Есть 2 вопроса: 1. Почему в этом коде экран перематывается только по событию (нажатие кнопки), но не перематывается в самом начале (код события также встроен в основную последовательность)?

#!/usr/bin/python3

import sys
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from time import time

text = ''
for i in range(10000):
	text += 'text' + str(i)+' '

if __name__=="__main__":
	def on_clicked():
		text_browser.setFocus()
		text_browser.ensureCursorVisible()
	app = QApplication(sys.argv)
	start_time = time()
	window = QWidget()
	window.setWindowTitle("Класс QTextEdit")
	text_browser = QTextEdit()
	text_browser.setHtml(text)
	cursor = text_browser.textCursor()
	cursor.setPosition(2000)
	print('text:',text_browser.toPlainText()[2000:2010])
	text_browser.setTextCursor(cursor)
	text_browser.setFocus()
	text_browser.ensureCursorVisible()
	button = QPushButton("Показать позицию с курсором")
	button.clicked.connect(on_clicked)
	box = QVBoxLayout()
	box.addWidget(text_browser)
	box.addWidget(button)
	window.setLayout(box)
	window.showMaximized()
	end_time = time()
	print('Завершено за %s с.' % (str(end_time - start_time)))
	sys.exit(app.exec_())

2. Самое главное. Предположим, что в QTextBrowser мне предстоит отображать некий html код, при этом я хочу производить ряд операций над текстом, который задан между тэгами, например, выделение, копирование, изменение форматирования и пр. Нужно, чтобы по клику мыши можно было бы однозначно определить, например, соответствующее место в html коде, в простом тексте, номер тэга и т.п. Как составить программу так, чтобы бóльшая часть расчетов пришлась на алгоритмы, встроенные в QT?

 ,

denton ()

RSS подписка на новые темы