# -*- 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_())