Example #1
0
    def __paint_title_background(self, painter: "QPainter"):
        """Paints a little background behind the title text, at the top of the node."""
        title_rect = self.__graphics_title.boundingRect()

        path_title_background = QPainterPath()
        path_title_background.setFillRule(Qt.WindingFill)
        path_title_background.addRoundedRect(
            0,
            0,
            self.background_paint_area().width(),
            title_rect.height(),
            self.round_edge_size,
            self.round_edge_size,
        )

        # (Drawing rects to hide the two botton round edges)
        path_title_background.addRect(
            0,
            title_rect.height() - self.round_edge_size,
            self.round_edge_size,
            self.round_edge_size,
        )

        path_title_background.addRect(
            self.background_paint_area().width() - self.round_edge_size,
            title_rect.height() - self.round_edge_size,
            self.round_edge_size,
            self.round_edge_size,
        )

        painter.setPen(Qt.NoPen)
        painter.setBrush(self.__title_background_brush)
        painter.drawPath(path_title_background.simplified())
Example #2
0
 def paint(self, painter, *args, **kwargs):
     margin = QMarginsF(3, 0, 3, 0)
     box = self.boundingRect().marginsAdded(margin)
     path = QPainterPath()
     path.addRoundedRect(box, 5, 5)
     painter.fillPath(path, QColor(*self.background_color))
     super().paint(painter, *args, **kwargs)
Example #3
0
    def paintEvent(self, event):
        super(BubbleLabel, self).paintEvent(event)
        painter = QPainter(self)
        painter.setRenderHint(QPainter.Antialiasing)  # 抗锯齿

        rectPath = QPainterPath()  # 圆角矩形
        triPath = QPainterPath()  # 底部三角形

        height = self.height() - 8  # 往上偏移8
        rectPath.addRoundedRect(QRectF(0, 0, self.width(), height), 5, 5)
        x = self.width() / 5 * 4
        triPath.moveTo(x, height)  # 移动到底部横线4/5处
        # 画三角形
        triPath.lineTo(x + 6, height + 8)
        triPath.lineTo(x + 12, height)

        rectPath.addPath(triPath)  # 添加三角形到之前的矩形上

        # 边框画笔
        painter.setPen(QPen(self.BorderColor, 1, Qt.SolidLine,
                            Qt.RoundCap, Qt.RoundJoin))
        # 背景画刷
        painter.setBrush(self.BackgroundColor)
        # 绘制形状
        painter.drawPath(rectPath)
        # 三角形底边绘制一条线保证颜色与背景一样
        painter.setPen(QPen(self.BackgroundColor, 1,
                            Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin))
        painter.drawLine(x, height, x + 12, height)
Example #4
0
 def group_object_pixmap(self, object_class_name):
     if object_class_name in self.group_obj_pixmap_cache:
         return self.group_obj_pixmap_cache[object_class_name]
     object_pixmap = self.object_pixmap(object_class_name)
     size = object_pixmap.size()
     width, height = size.width(), size.height()
     radius = width / 8
     pen_width = width / 32
     margin = width / 16
     pen = QPen(QApplication.palette().shadow().color())
     pen.setWidth(pen_width)
     path = QPainterPath()
     path.addRoundedRect(0, 0, width, height, radius, radius)
     pixmap = QPixmap(size)
     pixmap.fill(Qt.transparent)
     painter = QPainter(pixmap)
     painter.setRenderHint(QPainter.Antialiasing, True)
     painter.fillPath(path, QApplication.palette().window())
     painter.setPen(pen)
     painter.drawRoundedRect(pixmap.rect().adjusted(pen_width, pen_width, -pen_width, -pen_width), radius, radius)
     painter.drawPixmap(
         pixmap.rect().adjusted(margin, margin, -width / 2, -height / 2), object_pixmap, object_pixmap.rect()
     )
     painter.drawPixmap(
         pixmap.rect().adjusted(width / 2, margin, -margin, -height / 2), object_pixmap, object_pixmap.rect()
     )
     painter.drawPixmap(
         pixmap.rect().adjusted(width / 2, height / 2, -margin, -margin), object_pixmap, object_pixmap.rect()
     )
     painter.drawPixmap(
         pixmap.rect().adjusted(margin, height / 2, -width / 2, -margin), object_pixmap, object_pixmap.rect()
     )
     painter.end()
     self.group_obj_pixmap_cache[object_class_name] = pixmap
     return pixmap
Example #5
0
    def paint(self, painter, option, widget):
        path = QPainterPath()

        path.addRoundedRect(self.rect, 5, 5)

        painter.setBrush(QColor(255, 255, 255))
        painter.drawPath(path)
        painter.drawText(self.text_rect, self.text)
Example #6
0
    def paint(self, painter, option, widget):
        path = QPainterPath()

        path.addRoundedRect(self.rect, 5, 5)

        anchor = self.mapFromParent(self.chart.mapToPosition(self.anchor))

        if not self.rect.contains(anchor):
            point1 = QPointF()
            point2 = QPointF()

            # establish the position of the anchor point in relation to m_rect
            above = anchor.y() <= self.rect.top()
            aboveCenter = anchor.y() > self.rect.top() and anchor.y(
            ) <= self.rect.center().y()
            belowCenter = anchor.y() > self.rect.center().y() and anchor.y(
            ) <= self.rect.bottom()
            below = anchor.y() > self.rect.bottom()

            onLeft = anchor.x() <= self.rect.left()
            leftOfCenter = anchor.x() > self.rect.left() and anchor.x(
            ) <= self.rect.center().x()
            rightOfCenter = anchor.x() > self.rect.center().x() and anchor.x(
            ) <= self.rect.right()
            onRight = anchor.x() > self.rect.right()

            # get the nearest m_rect corner

            x = (onRight + rightOfCenter) * self.rect.width()
            y = (below + belowCenter) * self.rect.height()
            cornerCase = (above and onLeft) or (above and onRight) or (
                below and onLeft) or (below and onRight)
            vertical = qAbs(anchor.x() - x) > qAbs(anchor.y() - y)

            x1 = x + leftOfCenter * 10 - rightOfCenter * 20 + cornerCase * (
                not vertical) * (onLeft * 10 - onRight * 20)
            y1 = y + aboveCenter * 10 - belowCenter * 20 + cornerCase * vertical * (
                above * 10 - below * 20)

            x2 = x + leftOfCenter * 20 - rightOfCenter * 10 + cornerCase * (
                not vertical) * (onLeft * 20 - onRight * 10)
            y2 = y + aboveCenter * 20 - belowCenter * 10 + cornerCase * vertical * (
                above * 20 - below * 10)

            point1.setX(x1)
            point1.setY(y1)
            point2.setX(x2)
            point2.setY(y2)

            path.moveTo(point1)
            path.lineTo(anchor)
            path.lineTo(point2)

            path = path.simplified()

        painter.setBrush(QColor(255, 255, 255))
        painter.drawPath(path)
        painter.drawText(self.text_rect, self.text)
    def shape(self):
        frame_corner_radius = self.style().pixelMetric(
            Style.NodeFrameCornerRadius)

        path = QPainterPath()
        path.addRoundedRect(QRectF(QPointF(0, 0), self.size()),
                            frame_corner_radius, frame_corner_radius)

        return path
 def paint(self, painter, *args, **kwargs):
     if self.hovered:
         margin = QMarginsF(7, 5, 7, 5)
     else:
         margin = QMarginsF(3, 0, 3, 0)
     box = self.boundingRect().marginsAdded(margin)
     path = QPainterPath()
     path.addRoundedRect(box, 5, 5)
     painter.fillPath(path, self.background_color)
     super().paint(painter, *args, **kwargs)
Example #9
0
    def paint(self, painter, option, widget):
        path = QPainterPath()
        path.addRoundedRect(self._rect, 5, 5)
        anchor = self.mapFromParent(self._chart.mapToPosition(self._anchor))
        if not self._rect.contains(anchor) and not self._anchor.isNull():
            point1 = QPointF()
            point2 = QPointF()

            # establish the position of the anchor point in relation to _rect
            above = anchor.y() <= self._rect.top()
            aboveCenter = (anchor.y() > self._rect.top() and
                anchor.y() <= self._rect.center().y())
            belowCenter = (anchor.y() > self._rect.center().y() and
                anchor.y() <= self._rect.bottom())
            below = anchor.y() > self._rect.bottom()

            onLeft = anchor.x() <= self._rect.left()
            leftOfCenter = (anchor.x() > self._rect.left() and
                anchor.x() <= self._rect.center().x())
            rightOfCenter = (anchor.x() > self._rect.center().x() and
                anchor.x() <= self._rect.right())
            onRight = anchor.x() > self._rect.right()

            # get the nearest _rect corner.
            x = (onRight + rightOfCenter) * self._rect.width()
            y = (below + belowCenter) * self._rect.height()
            cornerCase = ((above and onLeft) or (above and onRight) or
                (below and onLeft) or (below and onRight))
            vertical = abs(anchor.x() - x) > abs(anchor.y() - y)

            x1 = (x + leftOfCenter * 10 - rightOfCenter * 20 + cornerCase *
                int(not vertical) * (onLeft * 10 - onRight * 20))
            y1 = (y + aboveCenter * 10 - belowCenter * 20 + cornerCase *
                vertical * (above * 10 - below * 20))
            point1.setX(x1)
            point1.setY(y1)

            x2 = (x + leftOfCenter * 20 - rightOfCenter * 10 + cornerCase *
                int(not vertical) * (onLeft * 20 - onRight * 10))
            y2 = (y + aboveCenter * 20 - belowCenter * 10 + cornerCase *
                vertical * (above * 20 - below * 10))
            point2.setX(x2)
            point2.setY(y2)

            path.moveTo(point1)
            path.lineTo(anchor)
            path.lineTo(point2)
            path = path.simplified()

        painter.setBrush(QColor(255, 255, 255))
        painter.drawPath(path)
        painter.drawText(self._textRect, self._text)
Example #10
0
    def __paint_outline(self, painter: "QPainter"):
        """Paints the outline of the node. Depending on if its selected or not, the
        color of the outline changes."""
        path_outline = QPainterPath()
        path_outline.addRoundedRect(
            self.boundingRect(),
            self.round_edge_size,
            self.round_edge_size,
        )

        painter.setPen(self.__outline_pen)
        painter.setBrush(Qt.NoBrush)
        painter.drawPath(path_outline.simplified())
Example #11
0
    def __paint_background(self, painter: "QPainter"):
        """Paints the background of the node. Plain color, no lines."""
        path_background = QPainterPath()
        path_background.addRoundedRect(
            self.background_paint_area(),
            self.round_edge_size,
            self.round_edge_size,
        )

        painter.setPen(Qt.NoPen)
        painter.setBrush(self.__background_brush)

        painter.drawPath(path_background.simplified())
Example #12
0
    def paintEvent(self, event):
        super(QtBubbleLabel, self).paintEvent(event)
        painter = QPainter(self)
        painter.setRenderHint(QPainter.Antialiasing)  # 抗锯齿

        rectPath = QPainterPath()  # 圆角矩形

        height = self.height() - 8  # 往上偏移8
        rectPath.addRoundedRect(QRectF(0, 0, self.width(), height), 5, 5)
        x = self.width() / 5 * 4
        # 边框画笔
        painter.setPen(
            QPen(self.BorderColor, 1, Qt.SolidLine, Qt.RoundCap, Qt.RoundJoin))
        # 背景画刷
        painter.setBrush(self.BackgroundColor)
        # 绘制形状
        painter.drawPath(rectPath)
Example #13
0
    def styleChange(self):
        self.prepareGeometryChange()
        style = self.style()

        # Size and Frame
        frame_width = style.pixelMetric(Style.NodeWidth)
        self._size.setWidth(frame_width)
        self._body_item.setPen(style.framePen(self.palette()))

        path = QPainterPath()
        path.addRoundedRect(QRectF(QPointF(), self.size()),
                            style.pixelMetric(Style.NodeFrameCornerRadius),
                            style.pixelMetric(Style.NodeFrameCornerRadius))
        self._body_item.setPath(path)

        # Title item
        title_font = style.font(Style.NodeTitleFont)
        title_metrics = QFontMetricsF(title_font)

        padding = style.pixelMetric(Style.NodeFrameTextPadding)

        self._title_item.setFont(title_font)
        self._title_item.setPos(padding, padding)
        self._title_item.moveBy(0, title_metrics.capHeight())
        self._title_item.setMaximumWidth(frame_width - padding * 2)

        # Divider item
        div_margin = style.pixelMetric(Style.NodeDividerTextMargin)
        div_voffset = padding + title_metrics.capHeight(
        ) + title_metrics.descent() + div_margin

        self._divider.setLine(0, div_voffset, frame_width, div_voffset)
        self._divider.setPen(style.framePen(self.palette()))

        # Description item
        self._description_item.setFont(style.font(Style.NodeDescriptionFont))
        self._description_item.setPos(padding, div_voffset + div_margin)
        self._description_item.setFrame(
            QRectF(
                QPointF(0, 0),
                QSizeF(
                    px(frame_width) - padding * 2,
                    (px(self.size().height()) - padding) -
                    (div_voffset + padding))))
Example #14
0
    def paint(self,
              painter=QPainter,
              option=QStyleOptionGraphicsItem,
              widget=QWidget):
        corners = 5
        body = self.boundingRect()
        height = body.height()
        width = body.width()
        percentage = height / 10
        painter.setRenderHint(QPainter.Antialiasing)

        path = QPainterPath()
        path.addRoundedRect(body, corners, corners)
        pen = QPen(QColor(255, 255, 255, 100),
                   3) if self.hover and not self.isPressed else QPen(
                       Qt.black, 0.1)
        pen.setJoinStyle(Qt.RoundJoin)
        pen.setCosmetic(True)
        painter.setPen(pen)
        painter.fillPath(path, self._model["bgColor"])
        painter.drawPath(path)
        if not self.isPressed:
            grad = QLinearGradient(0, height, 0, height - percentage)
            grad.setColorAt(0, QColor(175, 175, 175, 255))
            grad.setColorAt(1, QColor(175, 175, 175, 0))
            path = QPainterPath()
            path.addRoundedRect(body, corners, corners)
            painter.setCompositionMode(QPainter.CompositionMode_Multiply)
            painter.setPen(Qt.NoPen)
            painter.fillPath(path, grad)
            painter.drawPath(path)

            grad = QLinearGradient(0, percentage, 0, 0)
            grad.setColorAt(1, QColor(255, 255, 255, 255))
            grad.setColorAt(0, QColor(255, 255, 255, 0))
            path = QPainterPath()
            path.addRoundedRect(body, corners, corners)
            painter.setCompositionMode(QPainter.CompositionMode_Overlay)
            painter.setPen(Qt.NoPen)
            painter.fillPath(path, grad)
            painter.drawPath(path)
            painter.setCompositionMode(QPainter.CompositionMode_Source)
        else:
            path = QPainterPath()
            path.addRoundedRect(body, corners, corners)
            painter.setCompositionMode(QPainter.CompositionMode_Overlay)
            painter.setPen(Qt.NoPen)
            painter.fillPath(path, QColor(255, 255, 255))
            painter.drawPath(path)
            painter.setCompositionMode(QPainter.CompositionMode_Source)
        super(ButtonNode, self).paint(painter, option, widget)
Example #15
0
 def resizeEvent(self, r: QResizeEvent) -> None:
     """
     Qt Resize Event - does two things:
     1) applies rounded corners if window transparency has been disabled
     2) ensures resizer widgets and titlebar buttons stay in place
     TODO: the 'rounded_corner_px' value is harcoded. It relates to in '.TitleTabBar::tab' in
           widgetstyle/tabwidget_titlebar.py (border-width and border-image QSS attribute).
           Action: investigate a way so that this value doesn't have to be hard-coded.
     """
     # if transparency is turned off, set a mask for some basic rounded corners:
     if not self.__transparent_window and self.__style.window.WINDOW_CORNER_RADIUS_PX > 0:
         path = QPainterPath()
         path.addRoundedRect(
             QRectF(self.rect()),
             self.__style.window.WINDOW_CORNER_RADIUS_PX +
             1,  # add 1 to avoid drawing artifacts
             self.__style.window.WINDOW_CORNER_RADIUS_PX + 1)
         reg = QRegion(path.toFillPolygon().toPolygon())
         self.setMask(reg)
     # adjust window button positions
     if not isinstance(self.__window, QDIALOG_TYPES):
         self.resizer_bl.adjust_resizers(self.geometry(
         ))  # adjusting one resizer adjusts all other resizers too
     if self.__window_buttons_position == WINDOW_BUTTONS_RIGHT:
         self.__move_window_buttons()
     # if a titlebar tab widget is set, mask it so that the empty area can be used to drag the window
     if self.__tab_widget is not None:
         width = 0
         tab_bar = self.__tab_widget.tabBar()
         for i in range(0,
                        tab_bar.count() -
                        1):  # don't count invisible tab at end
             if tab_bar.isTabVisible(i):
                 width += tab_bar.tabRect(i).width()
         rounder_corner_px = 8  # TODO  # related to hardcoded border-image value in widgetstyle/tabwidget_titlebar.py
         r = QRect(0, 0, width + rounder_corner_px, self.__titlebar_height)
         self.__tab_widget.tabBar().setMask(r)
Example #16
0
    def setupUI(self):
        currentFilePath = os.path.dirname(__file__)

        # .uiファイルを読み込み
        loader = QUiLoader()
        uiFilePath = os.path.join(currentFilePath,
                                  'kkDisplayVertexColorSeparatelyGUI.ui')
        self.uiFIle = loader.load(uiFilePath)
        self.setCentralWidget(self.uiFIle)

        # scriptJobのparent設定のためにオブジェクト名を設定
        self.setObjectName("kkDisplayVertexColorSeparatelyWindow")

        # ウインドウのタイトルを指定
        self.setWindowTitle("kkDisplayVertexColorSeparately")

        # ウインドウのサイズを指定
        self.resize(200, 300)

        # UI要素にシグナルを追加
        self.setSignals()

        # SelectedNameに選択オブジェクト名を表示
        self.uiFIle.lineEdit_SelObj.setText(self.targetObj.name())

        # 内蔵のpaintVertexColourツールアイコンをセットする
        self.uiFIle.btn_PaintTool.setIcon(QIcon(':/paintVertexColour.png'))

        # フレームレスにする
        self.setWindowFlags(Qt.Window | Qt.FramelessWindowHint)

        # ウィンドウ自体の角を丸くする
        path = QPainterPath()
        path.addRoundedRect(self.rect(), 10, 10)
        region = QRegion(path.toFillPolygon().toPolygon())
        self.setMask(region)
Example #17
0
class QBlock(QCachedGraphicsItem):
    TOP_PADDING = 5
    BOTTOM_PADDING = 5
    LEFT_PADDING = 10
    RIGHT_PADDING = 10
    SPACING = 0
    AIL_SHOW_CONDITIONAL_JUMP_TARGETS = True
    SHADOW_OFFSET_X = 0
    SHADOW_OFFSET_Y = 0

    def __init__(self,
                 workspace,
                 func_addr,
                 disasm_view,
                 disasm,
                 infodock,
                 addr,
                 cfg_nodes,
                 out_branches,
                 scene,
                 parent=None):
        super().__init__(parent=parent)

        # initialization
        self.workspace = workspace
        self.func_addr = func_addr
        self.disasm_view = disasm_view
        self.disasm = disasm
        self.infodock = infodock
        self.variable_manager = infodock.variable_manager
        self.addr = addr
        self.cfg_nodes = cfg_nodes
        self.out_branches = out_branches
        self.scene = scene

        self._config = Conf

        self.objects = []  # instructions and labels
        self._block_item = None  # type: QPainterPath
        self._block_item_obj = None  # type: QGraphicsPathItem
        self.addr_to_insns = {}
        self.addr_to_labels = {}
        self.qblock_annotations = {}

        self._block_code_options: QBlockCodeOptions = QBlockCodeOptions()
        self._update_block_code_options()

        self._init_widgets()

        self._objects_are_hidden = False
        self._objects_are_temporarily_hidden = False

        self._create_block_item()

        self.setAcceptHoverEvents(True)

    #
    # Properties
    #

    @property
    def mode(self):
        raise NotImplementedError

    @property
    def width(self):
        return self.boundingRect().width()

    @property
    def height(self):
        return self.boundingRect().height()

    #
    # Public methods
    #

    def clear_cache(self):
        super().clear_cache()
        for obj in self.objects:
            obj.clear_cache()

    def _update_block_code_options(self):
        self._block_code_options.show_conditional_jump_targets = self.AIL_SHOW_CONDITIONAL_JUMP_TARGETS
        self._block_code_options.show_variables = self.disasm_view.show_variable
        self._block_code_options.show_variable_identifiers = self.disasm_view.show_variable_identifier

    def refresh(self):
        self._update_block_code_options()
        for obj in self.objects:
            obj.refresh()
        self.layout_widgets()
        self.recalculate_size()
        self._create_block_item()
        self.update()

    def reload(self):
        self._init_widgets()
        self.refresh()

    def size(self):
        return self.width, self.height

    def instruction_position(self, insn_addr):
        if insn_addr in self.addr_to_insns:
            insn = self.addr_to_insns[insn_addr]
            pos = insn.pos()
            return pos.x(), pos.y()

        return None

    #
    # Initialization
    #

    def _create_block_item(self):
        """
        Create the block background and border.
        """
        if self._block_item_obj is not None and self.scene is not None:
            self.scene.removeItem(self._block_item_obj)
            self._block_item = None
            self._block_item_obj = None

        self._block_item = QPainterPath()
        self._block_item.addRoundedRect(0, 0,
                                        self.width - self.SHADOW_OFFSET_X,
                                        self.height - self.SHADOW_OFFSET_Y,
                                        self._config.disasm_view_node_rounding,
                                        self._config.disasm_view_node_rounding)

    def _init_ail_block_widgets(self):
        bn = self.cfg_nodes
        if bn.addr in self.disasm.kb.labels:
            label = QBlockLabel(bn.addr,
                                get_label_text(bn.addr, self.disasm.kb),
                                self._config,
                                self.disasm_view,
                                self.workspace,
                                self.infodock,
                                parent=self)
            self.objects.append(label)
            self.addr_to_labels[bn.addr] = label

        # always add the block name as a label and instruction:
        block_name_label = QBlockLabel(bn.addr,
                                       f"loc_{hex(bn.addr)}:",
                                       self._config,
                                       self.disasm_view,
                                       self.workspace,
                                       self.infodock,
                                       parent=self)
        self.objects.append(block_name_label)
        self.addr_to_labels[bn.addr] = block_name_label

        for stmt in bn.statements:
            code_obj = QAilObj(stmt,
                               self.workspace,
                               self.infodock,
                               parent=None,
                               options=self._block_code_options)
            obj = QBlockCode(stmt.ins_addr,
                             code_obj,
                             self._config,
                             self.disasm_view,
                             self.workspace,
                             self.infodock,
                             parent=self)
            code_obj.parent = obj  # Reparent
            self.objects.append(obj)
            self.addr_to_insns[bn.addr] = obj

    def _init_disassembly_block_widgets(self):
        for obj in get_block_objects(self.disasm, self.cfg_nodes,
                                     self.func_addr):
            if isinstance(obj, Instruction):
                out_branch = get_out_branches_for_insn(self.out_branches,
                                                       obj.addr)
                insn = QInstruction(self.workspace,
                                    self.func_addr,
                                    self.disasm_view,
                                    self.disasm,
                                    self.infodock,
                                    obj,
                                    out_branch,
                                    self._config,
                                    parent=self)
                self.objects.append(insn)
                self.addr_to_insns[obj.addr] = insn
            elif isinstance(obj, Label):
                label = QBlockLabel(obj.addr,
                                    obj.text,
                                    self._config,
                                    self.disasm_view,
                                    self.workspace,
                                    self.infodock,
                                    parent=self)
                self.objects.append(label)
                self.addr_to_labels[obj.addr] = label
            elif isinstance(obj, IROp):
                code_obj = QIROpObj(obj, self.infodock, parent=None)
                disp_obj = QBlockCode(obj.addr,
                                      code_obj,
                                      self._config,
                                      self.disasm_view,
                                      self.workspace,
                                      self.infodock,
                                      parent=self)
                code_obj.parent = disp_obj  # Reparent
                self.objects.append(disp_obj)
            elif isinstance(obj, PhiVariable):
                if not isinstance(obj.variable, SimRegisterVariable):
                    phivariable = QPhiVariable(self.workspace,
                                               self.disasm_view,
                                               obj,
                                               self._config,
                                               parent=self)
                    self.objects.append(phivariable)
            elif isinstance(obj, Variables):
                for var in obj.variables:
                    variable = QVariable(self.workspace,
                                         self.disasm_view,
                                         var,
                                         self._config,
                                         parent=self)
                    self.objects.append(variable)
            elif isinstance(obj, FunctionHeader):
                self.objects.append(
                    QFunctionHeader(self.func_addr,
                                    obj.name,
                                    obj.prototype,
                                    obj.args,
                                    self._config,
                                    self.disasm_view,
                                    self.workspace,
                                    self.infodock,
                                    parent=self))

    def _init_widgets(self):
        if self.scene is not None:
            for obj in self.objects:
                self.scene.removeItem(obj)

        self.objects.clear()

        if isinstance(self.disasm, Clinic):
            self._init_ail_block_widgets()
        else:
            self._init_disassembly_block_widgets()

        self.layout_widgets()

    def layout_widgets(self):
        raise NotImplementedError()