Форум сайта python.su
Есть у меня многострочное поле, хочу в нём делать интернет-ссылки. Т.е. кликнул по ссылке, запустился браузер по умолчанию, а в нём открылась страница. Вроде как для этих целей должен подходить QTextBrowser, однако, после нажатия на ссылку, выведенный в поле текст пропадает. Меня это не устраивает. Мне нужно поведение типа, как в ворде или аналогичных редакторах, желательно без клавиши Ctrl.
Есть у меня набросок программы.
# Python 3 # -*- coding: utf-8 -*- import sys, webbrowser from PyQt4 import QtCore, QtGui from PyQt4.QtGui import (QWidget, qApp, QAction, QApplication, QHBoxLayout, QVBoxLayout, QGridLayout, QLabel, QLineEdit, QTextEdit, QPushButton, QComboBox, QCheckBox, QRadioButton, QFrame, QScrollArea, QTabWidget, QSizePolicy, QGroupBox, QFileDialog,QTextBrowser) from PyQt4.QtGui import QIcon, QPixmap, QPalette, QTextCursor from PyQt4.QtCore import QSize # ЦВЕТА ПОЛЕЙ sss_vivod = ("background-color: #456173; color: #f2f2f0; font: 14pt 'Courier New'") # ГРАФИКА class Window(QWidget): def __init__(self, parent=None): QWidget.__init__(self, parent) self.resize(200, 200) # шир / выс окна self.setWindowTitle('Заголовок') # Заголовок # БЛОК РАЗМЕТКИ #grid_os = QGridLayout() vbox = QVBoxLayout() # --- self.pole = QTextBrowser() self.pole.anchorClicked['QUrl'].connect(self.linkClicked) vbox.addWidget(self.pole) # --- self.setLayout(vbox) # --- --- Window.on_start(self) # ЛОГИКА def on_start(self): text = 'Некий текст<br>\ <a href="http://google.com">TEST LINK</a><br>\ Ещё текст' self.pole.setText(text) '''for i in data: self.pole.append(str(i))''' self.pole.moveCursor(QtGui.QTextCursor.Start) def linkClicked(self, url): print(url.toString()) webbrowser.open(url.toString()) # КОНЕЦ if __name__ == "__main__": app = QApplication(sys.argv) window = Window() window.show() sys.exit(app.exec_())
Отредактировано Kyrym (Янв. 9, 2018 14:55:55)
Офлайн
Kyrym ну елки-палки, вы опять напрочь игнорируете документацию?
http://doc.crossplatform.ru/qt/4.7.x/qtextbrowser.html#anchorClicked
там же английским по белому написано:
Note that the browser will automatically handle navigation to the location specified by link unless the openLinks property is set to false or you call setSource() in a slot connected. This mechanism is used to override the default navigation features of the browser.Тоесть простыми словами, щелкая по ссылке в QTextBrowser кутекстбраузер переходит по ссылке, или по крайней мере пытается это сделать, соответственно очищает поле, для отображения новой страницы.
Перевод:
Обратите внимание, что браузер автоматически обрабатывает навигацию в местоположении, указанном ссылкой, если для свойства openLinks не установлено значение false или вы вызываете setSource () в подключенном слоте. Этот механизм используется для переопределения навигационных функций по умолчанию браузера.
[code python][/code]
Отредактировано PEHDOM (Янв. 9, 2018 11:22:51)
Офлайн
Вообще-то документацию я читал, но как-то даже с переводом сложно понять, что setOpenLinks(False) делает то, что мне нужно.
Ладно, теперь работает.
Офлайн
Хм. обнаружил неведому ошибку.
В тестовой программе 1 поле-браузер и три кнопки, каждая из которых вставляет в поле текст. Первый текст с ссылкой, остальные без оной.
Запускаем программу, кликаем по второй кнопке, видим беленький текст (так и должно быть). Далее кликаем по первой кнопке, видим обычный белый текст + синюю ссылку. Кликаем по ссылке, открывается браузер, после чего переходим обратно в окно программы. Теперь , если мы нажмём на кнопку 2 или 3, то увидим, что наш белый обычный текст превратился в гиперссылку, причём содержание текста будет соответствовать тексту, вставляемому кнопками 2 и 3, а ссылка будет из первой кнопки (т.е. при нажатии на текст 2 или 3, мы перейдём по ссылке 1). Фиксируем ошибку.
Далее. Если мы снова нажмём кнопку 1, то увидим правильный текст по кнопке 1. Жмём кнопки 2 или 3, и видим, что текст стал снова обычным белым, гиперссылка исчезла.
Вопрос в том, как пофиксить ошибку и откуда она вообще берётся? Ведь текст вставляется через setText, т.е. затирая предыдущий.
Пока что, я решил вопрос, добавив в функцию def linkClicked(self, url): последней строчкой self.on_click_1(), но решение мне не очень нравится.
Примечально, что данное решение не работает без строчки:
self.pole_vivod.moveCursor(QtGui.QTextCursor.Start)
# Python 3 # -*- coding: utf-8 -*- import sys, webbrowser from PyQt4 import QtCore, QtGui from PyQt4.QtGui import (QWidget, qApp, QAction, QApplication, QHBoxLayout, QVBoxLayout, QGridLayout, QLabel, QLineEdit, QTextEdit, QPushButton, QComboBox, QCheckBox, QRadioButton, QFrame, QScrollArea, QTabWidget, QSizePolicy, QGroupBox, QFileDialog, QTextBrowser) from PyQt4.QtGui import QIcon, QPixmap, QPalette, QTextCursor from PyQt4.QtCore import QSize # ЦВЕТА ПОЛЕЙ sss_vivod = ("color: #f2f2f0; font: 14pt 'Courier New'") # ГРАФИКА class Window(QWidget): def __init__(self, parent=None): QWidget.__init__(self, parent) self.resize(250, 200) # шир / выс окна self.setWindowTitle('Заголовок') # Заголовок # БЛОК РАЗМЕТКИ grid_os = QGridLayout() # --- self.pole_vivod = QTextBrowser() self.pole_vivod.setStyleSheet(sss_vivod) self.pole_vivod.anchorClicked['QUrl'].connect(self.linkClicked) self.pole_vivod.setOpenLinks(False) # запрет удаления ссылки grid_os.addWidget(self.pole_vivod, 0,0) # --- --- vbox = QVBoxLayout() grid_os.addLayout(vbox, 0,1) # --- self.btn_1 = QPushButton('Текс 1') self.btn_1.clicked.connect(self.on_click_1) vbox.addWidget(self.btn_1) # --- self.btn_2 = QPushButton('Текс 2') self.btn_2.clicked.connect(self.on_click_2) vbox.addWidget(self.btn_2) # --- self.btn_3 = QPushButton('Текс 3') self.btn_3.clicked.connect(self.on_click_3) vbox.addWidget(self.btn_3) vbox.addStretch() # --- self.setLayout(grid_os) # --- --- # ЛОГИКА def on_click_1(self): text = 'Некий текст<br>\ <a href="http://python.su/forum/18/">TEST LINK</a><br>\ Ещё текст' self.pole_vivod.setText(text) self.pole_vivod.moveCursor(QtGui.QTextCursor.Start) def on_click_2(self): text = 'Текст второй кнопки' self.pole_vivod.setText(text) self.pole_vivod.moveCursor(QtGui.QTextCursor.Start) def on_click_3(self): text = 'Текст третьей кнопки' self.pole_vivod.setText(text) self.pole_vivod.moveCursor(QtGui.QTextCursor.Start) def linkClicked(self, url): webbrowser.open(url.toString()) # КОНЕЦ if __name__ == "__main__": app = QtGui.QApplication(sys.argv) window = Window() window.show() sys.exit(app.exec_())
Отредактировано Kyrym (Янв. 12, 2018 10:19:10)
Офлайн