1

我正在使用 Python 2.7 和 PySide(Qt 包装器)开发一个 GUI 应用程序。

我想让标注小部件浮动在其他小部件上方(类似于工具提示),但不使用标准工具提示框架,该框架基本上为小部件分配工具提示并在悬停时显示它。

我想即时启动它们的显示和控制位置(相对于下面的小部件)、大小和内容,并销毁它们。

是否可以简单地覆盖基本的 QWidget 并将其显示在应用程序之上?

4

1 回答 1

1

在这里询问并查看了很多其他地方之后,我发现这可以使用一个简单的 QWidget 子类来实现,该子类显示为顶级窗口,没有框架并使用一些 QRegion 技巧来创建标注。

这是我创建的代码,以防有人需要这样的东西:

from PySide.QtCore import *
from PySide.QtGui import *
import sys

def createMask(size):
    w=size.width()
    h=size.height()
    img=QImage(size, QImage.Format_MonoLSB)
    qp=QPainter()
    qp.begin(img)
    qp.fillRect(QRect(QPoint(0, 0), size), QColor(255,255,255))
    path=QPainterPath()
    path.moveTo(0, h-1)
    path.lineTo(w-1,0)
    path.lineTo(h-1, 0)
    path.lineTo(0, h-1)
    qp.fillPath(path, QBrush(QColor(0, 0, 0)))
    qp.end()
    return img

def createRoundedRectRegion(rect, radius):
    r=QRegion(rect.adjusted(radius, 0, -radius, 0))
    r|=QRegion(rect.adjusted(0, radius, 0, -radius))
    r|=QRegion(rect.left(), rect.top(), 2*radius, 2*radius, QRegion.Ellipse)
    r|=QRegion(rect.right()-2*radius, rect.top(), 2*radius, 2*radius, QRegion.Ellipse)
    r|=QRegion(rect.left(), rect.bottom()-2*radius, 2*radius, 2*radius, QRegion.Ellipse)
    r|=QRegion(rect.right()-2*radius, rect.bottom()-2*radius, 2*radius, 2*radius, QRegion.Ellipse)
    return r

def createRegion(bubbleSize, pointSize, offset):
    r=createRoundedRectRegion(QRect(QPoint(0, 0), bubbleSize), 10)
    t=QRegion(QPixmap(createMask(pointSize)))
    t.translate(offset, bubbleSize.height())
    r|=t
    return r

class Callout(QWidget):
    def __init__(self, text, parent=None):
        super(Callout, self).__init__(parent)
        w=100+len(text)*5
        self.setMinimumSize(w, 100)
        self.setMaximumSize(w, 100)
        self.text=text
        self.setWindowFlags(Qt.FramelessWindowHint|Qt.WindowStaysOnTopHint)
        self.setAttribute(Qt.WA_TranslucentBackground)
        self.setMask(createRegion(QSize(w, 50), QSize(75, 50), 75))

    def paintEvent(self, event):
        qp=QPainter()
        qp.begin(self)
        qp.fillRect(0, 0, self.width(), 200, QColor(192, 192, 192))
        qp.drawText(QRect(0, 0, self.width(), 50), Qt.AlignCenter, self.text)
        qp.end()

def main():
    app=QApplication(sys.argv)
    w=Callout('Bla Bla Bla')
    w.move(200, 100)
    w.show()
    app.exec_()

if __name__ == '__main__':
    main()
于 2013-05-13T21:24:35.377 回答