fereria
7/21/2019 - 2:38 PM

Original Tooltip Window

# -*- coding: utf-8 -*-

import sys
import os
import os.path

from PySide2 import QtCore, QtGui, QtWidgets
from PySide2.QtUiTools import QUiLoader

ZOOM_MIN = -0.5
ZOOM_MAX = 2
GRID_STEP = 20

# MainUI


class UISample(QtWidgets.QDialog):

    def __init__(self, parent=None):

        super(UISample, self).__init__((parent))

        self.view = NodeView()
        layout  = QtWidgets.QVBoxLayout()
        self.setLayout(layout)
        layout.addWidget(self.view)

        self.scene = NodeScene()
        self.view.setScene(self.scene)

        self.resize(400, 300)

        # Item追加
        item = BaseNodeItem()
        self.scene.addItem(item)


class NodeView(QtWidgets.QGraphicsView):

    def __init__(self, parent=None):
        super(NodeView, self).__init__(parent)

        self.setMouseTracking(True)

    def wheelEvent(self, e):
        delta = e.delta()
        adjust = (delta / 120) * 0.1
        self.set_zoom(adjust)

    def set_zoom(self, value):

        scale = 0.0
        # 今のズーム率 指定外にはならないようにする
        zoom = self.get_zoom()
        if ZOOM_MIN >= zoom:
            if value < 0.0:
                return
        if ZOOM_MAX <= zoom:
            if value > 0.0:
                return
        scale = 0.9 if value < 0.0 else 1.1
        self.scale(scale, scale)

    def get_zoom(self):
        transform = self.transform()
        cur_scale = (transform.m11(), transform.m22())
        return float('{:0.2f}'.format(cur_scale[0] - 1.0))


class NodeScene(QtWidgets.QGraphicsScene):

    sel_item = None

    def __init__(self, parent=None):
        super(NodeScene, self).__init__(parent)

    def viewer(self):
        return self.views()[0] if self.views() else None

    def drawBackground(self, painter, rect):
        # Grid表示をする
        painter.setPen(QtGui.QColor(200, 200, 255, 125))

        # 横線を作る
        st = rect.top() + GRID_STEP
        scene_height = rect.bottom()
        if rect.top() < -1 * GRID_STEP:
            st = rect.top()
            scene_height -= rect.top()

        for i in range(int(scene_height / GRID_STEP) + 1):
            # start_x,y end_xy
            line_val = st + (i * GRID_STEP)
            painter.drawLine(rect.left(), line_val, rect.right(), line_val)

         # 縦線を作る
        st = rect.left()
        scene_width = rect.right()
        if st < GRID_STEP * -1:
            st = rect.left()
            scene_width -= rect.left()

        for i in range(int(scene_width / GRID_STEP) + 1):
            line_val = st + (i * GRID_STEP)
            painter.drawLine(line_val, rect.top(), line_val, rect.bottom())

        self.update()


class BaseNodeItem(QtWidgets.QGraphicsItem):

    def __init__(self, parent=None):

        super(BaseNodeItem, self).__init__(parent)

        self._width = 200
        self._height = 100

        self.color = [255, 0, 0]
        self.tooltip = None
        self.tooltipText = "hogehoge"

        self.setAcceptHoverEvents(True)
        self.setFlags(self.ItemIsSelectable | self.ItemIsMovable)

    def boundingRect(self):

        return QtCore.QRectF(0.0, 0.0, self._width, self._height)

    def paint(self, painter, option, widget):

        margin = 20
        rect = self.boundingRect()
        dis_rect = QtCore.QRectF(rect.left() - (margin / 2),
                                 rect.top() - (margin / 2),
                                 rect.width() + margin,
                                 rect.height() + margin)

        pen = QtGui.QPen(QtGui.QColor(*self.color), 8)
        bg_color = QtGui.QColor(*self.color)
        painter.setPen(pen)
        painter.setBrush(bg_color)
        painter.drawRoundedRect(dis_rect, 5, 5)

    def hoverEnterEvent(self, e):

        self.tooltip = MyPopup("hogehogefugafuga", parent=self.window())
        self.tooltip.show()

    def hoverMoveEvent(self, e):

        if self.tooltip is not None:
            self.tooltip.positionUpdate()

    def hoverLeaveEvent(self, e):

        self.tooltip.close()
        self.tooltip = None


class MyPopup(QtWidgets.QDialog):
    def __init__(self, text="", width=200, height=100, positionOffset=10, parent=None):
        super(MyPopup, self).__init__(parent)

        self._text = text

        self.color = [0, 0, 255]
        self.tooltipWidth = width
        self.tooltipHeight = height
        self.positionOffset = positionOffset
        # 枠を消して、透明にする
        self.setWindowFlags(QtCore.Qt.FramelessWindowHint)
        self.setAttribute(QtCore.Qt.WA_TranslucentBackground)

        self.positionUpdate()

    def setText(self, text):
        self._text = text
        self.update()

    def getText(self):
        return self._text

    def positionUpdate(self):
        pos = QtGui.QCursor().pos()
        self.setGeometry(pos.x() + self.positionOffset,
                         pos.y() + self.positionOffset,
                         self.tooltipWidth,
                         self.tooltipHeight)

    def paintEvent(self, event):
        painter = QtGui.QPainter(self)

        pen = QtGui.QPen(QtGui.QColor(*self.color), 8)
        bg_color = QtGui.QColor(*self.color)
        painter.setPen(pen)
        painter.setBrush(bg_color)
        rect = QtCore.QRect(0, 0, self.geometry().width(), self.geometry().height())
        painter.drawRoundedRect(rect, 20, 20)
        # 文字を描画
        painter.setFont(QtGui.QFont(u'メイリオ', 20, QtGui.QFont.Bold, False))
        painter.setPen(QtCore.Qt.white)
        painter.drawText(QtCore.QPoint(10, 30), self.getText())


if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    a = UISample()
    a.show()
    sys.exit(app.exec_())