Найти - Пользователи
Полная версия: Навигация по QTextEdit/QTextBrowser
Начало » GUI » Навигация по QTextEdit/QTextBrowser
1 2
vanvanov
Продолжаю изучение 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?
Rodegast
Самое главное что тебе следует познать, это то что Qt != tkinter По этому прежде чем пытаться изучать PyQt нужно изучить ООП.

> Почему в этом коде экран перематывается только по событию (нажатие кнопки), но не перематывается в самом начале (код события также встроен в основную последовательность)?

Потому что виджет ещё не отобразился.

> Предположим, что в QTextBrowser мне предстоит отображать некий html код, при этом я хочу производить ряд операций над текстом

Редактировать HTML проще всего при помощи QWebView. Но тебе до этого ещё очень далеко…
vanvanov
Rodegast
Самое главное что тебе следует познать, это то что Qt != tkinter По этому прежде чем пытаться изучать PyQt нужно изучить ООП.
Я не программист. Программирование - мое хобби, и то, сугубо с прагматическим уклоном. В одной проге, уже написанной с использованием tkinter, потребовалось сделать табличку, чтобы текст лучше воспринимался. В tkinter с этим проблемы, решил попробовать Qt. На форумах советуют освоить основы С++, потому что многие примеры и учебники написаны для этого языка. Вы советуете освоить ООП. Чувствую, в следующий раз мне предложат прочитать все книги Кнута. Нет, я понимаю, что это все правильно и расширяет кругозор, улучшает код и потенциально уменьшает число производимых велосипедов. Я и сам стараюсь не писать индусский код. Но программирование - штука весьма затратная по времени, а время - весьма большая роскошь, особенно когда программирование дается тебе нелегко и это не твоя профессия.

Потому что виджет ещё не отобразился.
Т.е. надо искать костыли по типу update_idletasks? А вы говорите, != tkinter. Причем тут ООП, я тоже не понял.

Редактировать HTML проще всего при помощи QWebView.
Мне не нужно его редактировать. Нужно просто найти тэг по клику мыши.
Rodegast
> Я не программист. Программирование - мое хобби
Такая отмазка не пройдёт. Если и заниматься чем-то, то нужно это делать более-менее качественно. Иначе будет пустая трата времени.

> На форумах советуют освоить основы С++
Это не обязательно. Достаточно знать основы синтаксиса.

> Вы советуете освоить ООП
GUI без классов не пишется. Без ООП получится унылая кучка ГК и всё.

> Т.е. надо искать костыли по типу update_idletasks
Я не в курсе что такое update_idletasks. Тебе надо сначала вызвать .show() и только потом курсор дёргать.
vanvanov
Rodegast
Тебе надо сначала вызвать .show() и только потом курсор дёргать.
Спасибо за намек. Переделал в классы. Так лучше? Курсор уже становится в нужное место, но ensureCursorVisible по-прежнему не срабатывает.
#!/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
html_code = ''
for i in range(10000):
		html_code += 'text' + str(i)+' '
class createGUI(QTextEdit):
	def __init__(self):
		QTextEdit.__init__(self)
		self.setHtml(html_code)
	def update_cursor(self):
		cursor = self.textCursor()
		# text263
		cursor.setPosition(2000)
		self.setTextCursor(cursor)
		self.setFocus()
		self.ensureCursorVisible()
if __name__=="__main__":
		app = QApplication(sys.argv)
		start_time = time()
		widget = createGUI()
		widget.showMaximized()
		widget.update_cursor()
		end_time = time()
		print('Finished in %s s.' % (str(end_time - start_time)))
		sys.exit(app.exec_())
Rodegast
Так намного лучше. Но окно от виджетов наследовать не надо, для этого есть QMainWindow + посмотри как пользоваться дизайнером.

> ensureCursorVisible по-прежнему не срабатывает
Устанавливать фокус не нужно
vanvanov
Попытался сделать через QMainWindow, в итоге виджет text_browser не занимает все пространство, выделенное под QMainWindow.

Пробовал
self.text_browser.setSizePolicy(QSizePolicy.Maximum,QSizePolicy.Maximum)
но это не помогает. Прочитал в интернете, что, если сделать слои, то виджеты будут автоматически подстраиваться по размеру. Но в коде:
#!/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
html_code = ''
for i in range(10000):
	html_code += 'text' + str(i) + ' '
class myWindow(QMainWindow):
	def __init__(self):
		QMainWindow.__init__(self)
		self.setWindowTitle("Класс QTextEdit")
		self.layout = QVBoxLayout()
		self.text_browser = QTextEdit(self)
		self.text_browser.setHtml(html_code)
		self.layout.addWidget(self.text_browser)
		self.setLayout(self.layout)
if __name__=="__main__":
	app = QApplication(sys.argv)
	start_time = time()
	window = myWindow()
	window.showMaximized()
	end_time = time()
	print('Finished in %s s.' % (str(end_time - start_time)))
	sys.exit(app.exec_())
получаю QWidget::setLayout: Attempting to set QLayout “” on myWindow “”, which already has a layout.
Rodegast
import sys
from PySide import QtCore, QtGui
from time import time
html_code = "text"*100
class myWindow(QtGui.QMainWindow):
	def __init__(self):
		QtGui.QMainWindow.__init__(self)
		self.setWindowTitle("Класс QTextEdit")
		self.centralwidget = QtGui.QWidget(self)
		layout = QtGui.QVBoxLayout(self.centralwidget)
		self.text_browser = QtGui.QTextEdit(self)
		self.text_browser.setHtml(html_code)
		layout.addWidget(self.text_browser)
		self.setCentralWidget(self.centralwidget)
if __name__=="__main__":
	app = QtGui.QApplication(sys.argv)
	start_time = time()
	window = myWindow()
	window.showMaximized()
	end_time = time()
	print('Finished in %s s.' % (str(end_time - start_time)))
	sys.exit(app.exec_())
vanvanov
Rodegast
Спасибо, но на этом проблемы не закончились. Когда я пытаюсь сделать ensureCursorVisible, прокрутка идет куда-то не туда, до text1649 (по моим расчетам, позиция 2000 соответствует text263). При этом, если закомментировать centralwidget и layout, прокручивается нормально:

Код сейчас выглядит так:
#!/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
html_code = ''
for i in range(10000):
	html_code += 'text' + str(i) + ' '
class myWindow(QMainWindow):
	def __init__(self):
		QMainWindow.__init__(self)
		self.setWindowTitle("Класс QTextEdit")
		self.centralwidget = QWidget(self)
		self.layout = QVBoxLayout(self.centralwidget)
		self.text_browser = QTextEdit(self)
		self.text_browser.setHtml(html_code)
		self.layout.addWidget(self.text_browser)
		self.setCentralWidget(self.centralwidget)
	def update_cursor(self):
		cursor = self.text_browser.textCursor()
		# text263
		cursor.setPosition(2000)
		self.text_browser.setTextCursor(cursor)
		self.text_browser.ensureCursorVisible()
if __name__=="__main__":
	app = QApplication(sys.argv)
	start_time = time()
	window = myWindow()
	window.setWindowTitle("Класс QTextEdit")
	window.showMaximized()
	window.update_cursor()
	end_time = time()
	print('Finished in %s s.' % (str(end_time - start_time)))
	sys.exit(app.exec_())
Если я туплю, и эти вещи мог бы решить без форума, подскажите, пожалуйста, как построить свое обучение.
Rodegast
Сделай так и посмотри там ли прокрутка:

html_code = "".join(['text%i<br>'%x for x in range(10000)])
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB