为什么QWebView中的很多QWebElements都是Null
?虽然它们在html中似乎完全有效。
以下是使用PySide的演示:
from PySide.QtGui import QWidget, QMainWindow, QApplication, QVBoxLayout,\
QLineEdit, QPainter, QPen
from PySide.QtCore import QUrl, Qt
from PySide.QtWebKit import QWebView, QWebElement
import sys
class Window(QMainWindow):
def __init__(self, parent=None):
super(Window, self).__init__(parent)
layout = QVBoxLayout()
self.lineedit_search = QLineEdit()
self.lineedit_search.editingFinished.connect(self.loadBrowser)
self.lineedit_search.setText("http://www.imdb.com/chart/top")
self.browser = MouseSensitiveWebView()
self.browser.setUrl(QUrl("http://www.imdb.com/chart/top"))
layout.addWidget(self.lineedit_search)
layout.addWidget(self.browser)
layout_widget = QWidget()
layout_widget.setLayout(layout)
self.setCentralWidget(layout_widget)
def loadBrowser(self):
txt = self.lineedit_search.text()
self.browser.load(QUrl(txt))
class MouseSensitiveWebView(QWebView):
def __init__(self, parent=None):
super(MouseSensitiveWebView, self).__init__(parent)
self.setMouseTracking(True)
self._hover_rect = None
self._hit_elem = None
def mouseMoveEvent(self, mme):
mouse_pos = mme.pos()
hit_test_result = self.page().mainFrame().hitTestContent(mouse_pos)
if hit_test_result:
new_rect = hit_test_result.boundingRect()
if new_rect == self._hover_rect: # don't repaint unless the hovered element changed
return
hit_elem = hit_test_result.element()
if hit_elem.isNull():
print("{0} is Null".format(hit_elem))
else:
print("{0} is not Null".format(hit_elem))
self._hover_rect = new_rect
self._hit_elem = hit_elem
self.repaint()
else:
self._hover_rect = None
def paintEvent(self, pe):
if not self._hover_rect:
super(MouseSensitiveWebView, self).paintEvent(pe)
else:
super(MouseSensitiveWebView, self).paintEvent(pe)
# get the current horizontal and vertical scroll bar positions
main_frame = self.page().mainFrame()
hor_pos, ver_pos = main_frame.scrollBarValue(Qt.Horizontal), main_frame.scrollBarValue(Qt.Vertical)
# move the hover rect by these values
hover_rect = self._hover_rect
hover_rect.moveTop(hover_rect.top() - ver_pos)
hover_rect.moveLeft(hover_rect.left() - hor_pos)
painter = QPainter(self)
pen = QPen(Qt.red)
pen.setWidth(2)
painter.setPen(pen)
painter.drawRect(hover_rect)
if __name__ == "__main__":
app = QApplication(sys.argv)
main = Window()
main.setGeometry(50, 50, 800, 600)
main.show()
sys.exit(app.exec_())
只需保持鼠标悬停,就会在您正在悬停的元素周围绘制一个红色方块。如果它为null,则它将记录到控制台。
您会注意到大多数可见元素实际上是Null
。这使得QWebView
在页面元素上运行时变得不那么有用。这也适用于PyQt4
,在这方面看起来相似或事件更糟,并且获得更多Null。
答案 0 :(得分:0)
首先,null元素的问题似乎最近已归档为bug。
我已经做了一些解决方法,只允许选择来自内联系列的链接(<a>
元素)。我得到他们的文本并在封闭的父母中搜索具有该文本的元素:
def mouseMoveEvent(self, mme):
mouse_pos = mme.pos()
hit_test_result = self.page().mainFrame().hitTestContent(mouse_pos)
if hit_test_result:
new_rect = hit_test_result.boundingRect()
if new_rect == self._hover_rect: # don't repaint unless the hovered element changed
return
hit_elem = hit_test_result.element()
if hit_elem.isNull():
enclosing = hit_test_result.enclosingBlockElement()
elem_text = hit_elem.linkText() # works only for <a> elements
for subelement in enclosing.findAll('*'):
if subelement.toPlainText() == elem_text:
print "Found Link {}".format(subelement)
break
else:
print("Element is null and not a link")
else:
print("{0} is not Null".format(hit_elem))
self._hover_rect = new_rect
self._hit_elem = hit_elem
self.repaint()
else:
self._hover_rect = None