Example #1
0
class PreviewTooltip(QWidget):
    def __init__(self, url):
        QWidget.__init__(self, None, Qt.ToolTip)
        self.url = url
        
        self.font = QFont(QApplication.font(self))
        self.font.setPointSize(8)
        
        desktop = QApplication.desktop().availableGeometry(self)
        cursor = QCursor.pos()
        rect = QRect(cursor + QPoint(-10, 10), QSize(240,180 + QFontMetrics(self.font).height()))
        if rect.left() < desktop.left():
            rect.moveLeft(desktop.left())
        if rect.right() > desktop.right():
            rect.moveRight(cursor.x() - 10)
        if rect.bottom() > desktop.bottom():
            rect.moveBottom(cursor.y() - 10)
        self.setGeometry(rect)
        
        self.pixmap = None
        self.progress = 0
        self.title = unicode(self.url)

        self.webView = QWebView()
        self.webView.page().mainFrame().setScrollBarPolicy(Qt.Horizontal, Qt.ScrollBarAlwaysOff)
        self.webView.page().mainFrame().setScrollBarPolicy(Qt.Vertical, Qt.ScrollBarAlwaysOff)
        self.webView.resize(1024,768)
        self.webView.load(QUrl(url))
        
        self.timer = QTimer(self)
        self.connect(self.timer, SIGNAL("timeout()"), self.refresh)
        self.timer.start(3000)
        
        self.connect(self.webView, SIGNAL("loadFinished(bool)"), self.refresh)
        self.connect(self.webView, SIGNAL("loadProgress(int)"), self.updateProgress)
        self.connect(self.webView, SIGNAL("urlChanged(const QUrl&)"), self.newUrl)
        self.connect(self.webView, SIGNAL("titleChanged(const QString&)"), self.newTitle)

    def updateProgress(self, progress):
        self.progress = progress
        self.update()
    
    def newUrl(self, url):
        self.title = unicode(url.toString())
        self.update()
    
    def newTitle(self, title):
        self.title = unicode(title)
        self.update()

    def refresh(self):
        view = QPixmap(self.webView.size())
        self.webView.render(view)
        self.pixmap = view.scaled(QSize(240,180), Qt.IgnoreAspectRatio, Qt.SmoothTransformation)
        self.update()
    
    def paintEvent(self, event):
        QWidget.paintEvent(self, event)
        p = QPainter(self)
        p.setFont(self.font)
        if self.pixmap:
            p.drawPixmap(QPoint(0,0), self.pixmap)
        r = QRect(self.rect().topLeft() + QPoint(0, 180), QSize(self.rect().size().width(), p.fontMetrics().height()))
        p.fillRect(r, self.palette().midlight())
        if self.progress:
            pr = QRect(r)
            pr.setWidth( (r.width() * self.progress) / 100 )
            p.fillRect(pr, self.palette().dark())
        p.setBrush(Qt.NoBrush)
        p.setPen(QPen(self.palette().text(), 1))
        p.drawText(QRectF(r), self.title, QTextOption(Qt.AlignHCenter))
        p.setPen(QPen(self.palette().shadow(), 1))
        p.drawRect(self.rect().adjusted(0,0,-1,-1))
Example #2
0
class MListWidget(QListWidget):
    '''Allows setting HTML items instead of just text.
    This is a nasty hack, unfortunately - thanks to some unfortunate Qt API decicions (QLabel inconsistently hides certain internals :( )
    '''
    gainedFocus = pyqtSignal()
    lostFocus = pyqtSignal()

    def __init__(self, parent = None):
        QListWidget.__init__(self, parent)

        self._htmlItemLabel = None
        self._htmlItemWidget = None
        self._htmlItemWidgetFinishedLoading = False

        self._prepHtmlItemWidget()

    #def focusInEvent(self, event):
        #self.gainedFocus.emit()
        #event.accept()
        #QListWidget.focusInEvent(self, event)
    
    #def focusOutEvent(self, event):
        #self.lostFocus.emit()
        #event.accept()
        #QListWidget.focusOutEvent(self, event)

    #def event(self, event):
        #if event.type() == QEvent.InputMethod:
            #print 'ionout pmethod'
            #self.inputMethodEvent(event)
        #elif event.type() == QEvent.KeyPress:
            #print 'key pressed'
        #return QListWidget.event(self, event)

    #@pyqtSignature('QInputMethodEvent')
    #def inputMethodEvent(self, event):
        #print 'custom input event!'
        #print event

    def event(self, event):
        '''Intercept enter/return presses.
        '''
        if event.type() == QEvent.KeyPress:
            key_press = QKeyEvent(event)
            if key_press.key() in [Qt.Key_Enter, Qt.Key_Return]:
                self.returnPressed.emit()
                return True
        return QListWidget.event(self, event)

    def _htmlItemWidgetLoadedSignal(self, ok):
        self._htmlItemWidgetFinishedLoading = True

    def _prepHtmlItemWidget(self):
        self._htmlItemWidget = QWebView()
        hw = self._htmlItemWidget

        hw.loadFinished.connect(self._htmlItemWidgetLoadedSignal)

        #TODO hw.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        #hw.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)

        # font
        ws = hw.settings()
        font_size = self.font().pointSize()
        ws.setFontSize(QWebSettings.DefaultFontSize, font_size)
        ws.setFontFamily(QWebSettings.StandardFont, self.font().family())

        # transparency
        palette = hw.palette()
        palette.setBrush(QPalette.Base, Qt.transparent)
        hw.page().setPalette(palette)
        hw.setAttribute(Qt.WA_OpaquePaintEvent, False)

        # better rendering
        hw.setRenderHint(QPainter.Antialiasing, True)
        hw.setRenderHint(QPainter.TextAntialiasing, True)
        hw.setRenderHint(QPainter.SmoothPixmapTransform, True)
        hw.setRenderHint(QPainter.HighQualityAntialiasing, True)

        hw.setHtml(u'')
        h = font_size + 6
        hw.setFixedHeight(h)
        


    def addHtmlItem(self, html, data):
        '''Adds a new QTextEdit widget containing the given HTMl as an item in the list.
        '''
        item = QListWidgetItem()
        item.setData(Qt.UserRole, data)
        self.addItem(item)
        item.setSizeHint(self._htmlItemWidget.frameSize())

        label = QLabel()
        label.setTextInteractionFlags(Qt.NoTextInteraction)

        html = u'<html><body style="margin:0px 0px 0px 4px">{0}</body></html>'.format(html)

        if '<img' in html:
            self._htmlItemWidgetFinishedLoading = False
            self._htmlItemWidget.setHtml(html)

            pm = QImage(self._htmlItemWidget.size(), QImage.Format_ARGB32)
            pm.fill(Qt.transparent)

            # wait for it to finish loading, then render
            q_app = QApplication.instance()
            while not self._htmlItemWidgetFinishedLoading:
                q_app.processEvents(QEventLoop.WaitForMoreEvents | QEventLoop.ExcludeUserInputEvents)
            
            self._htmlItemWidget.render(pm, flags=QWidget.DrawChildren)

            label.setPixmap(QPixmap.fromImage(pm))
        else:
            label.setText(html)
        
        self.setItemWidget(item, label)