簡體   English   中英

在 pyqt5 中創建自定義小部件

[英]Creating custom widget in pyqt5

我知道有特定於這個主題的答案,但我正在嘗試創建一個如下所示的節點小部件

在此處輸入圖片說明

這是我試過的代碼。

from PyQt5.QtWidgets import *


class NNodeLayout(QWidget):

    def __init__(self, container):
        super(NNodeLayout, self).__init__(container)
        
        self.node_frame = QFrame(container)

        self.node_frame.setFrameShape(QFrame.StyledPanel)
        self.node_frame.setStyleSheet('background-color: blue')
        self.node_frame.setMinimumSize(50, 50)

        self.node_frame_layout = QVBoxLayout()
        self.node_frame_grid_layout = QGridLayout()  
        self.node_frame_layout.setSpacing(0)
        self.node_frame_layout.setContentsMargins(0, 0, 0, 0)
        self.node_frame_grid_layout.setContentsMargins(5, 0, 5, 0)

        self.node_frame_layout.addWidget(QLabel('hello: '))
        self.node_frame_layout.addLayout(self.node_frame_grid_layout)
        self.node_frame.setLayout(self.node_frame_layout)


    def n_label(self, lbl_name):
        print(lbl_name)
        lbl = QLabel(lbl_name)
        lbl.setStyleSheet('background-color:blue')
        self.node_frame_grid_layout.addWidget(lbl)

    def n_input(self, place_holder = ""):
        text_input = QLineEdit()
        text_input.placeholderText(place_holder)
        self.node_frame_grid_layout.addWidget(text_input)

    def n_input_point_shape_color(self):
        pass

    def n_top_bar(self):
        pass

    def n_move(self, x, y):
        self.node_frame.move(x, y)

    def n_resize(self, width, height):
        self.node_frame.resize(width, height)

    def n_geometry(self):
        return self.node_frame.geometry()

我需要添加那些標記為紅色的套接字以顯示在文本旁邊

不幸的是,您不能直接從子部件中繪制父部件。 或者,更好,你可以,但如果你有很多孩子,它可能會導致一些性能問題,因為每個孩子都會請求對父級重新繪制,這並不好。

另一方面,您的方法存在一些問題:不僅您的 NNodeLayout不是布局,而且您實際上並未使用它,因為您正在添加另一個小部件(框架)。

最簡單的解決方案是創建包含 2 個嵌套垂直布局的 QFrame 的子類,並重新實現繪制事件。

class NodeFrame(QFrame):
    _margin = 4
    _styleSheet = '''
            NodeFrame {{
                border: 1px solid white;
                border-radius: {0}px;
                background: #3f3f3f;
                margin: {0}px;
            }}
            QWidget {{
                color: white;
            }}
            QLineEdit {{
                color: palette(text);
            }}
        '''
    def __init__(self, parent=None):
        super().__init__(parent)

        layout = QVBoxLayout(self)
        self.headerLayout = QVBoxLayout()
        layout.addLayout(self.headerLayout)
        self.contentLayout = QVBoxLayout()
        layout.addLayout(self.contentLayout)

        self.options = []
        self.setMargin(self._margin)

    def setMargin(self, margin):
        self._margin = max(4, margin)
        self.setStyleSheet(self._styleSheet.format(self._margin))

    def addHeaderWidget(self, widget):
        self.headerLayout.addWidget(widget)

    def removeHeaderWidget(self, widget):
        self.headerLayout.removeWidget(widget)

    def addOption(self, widget, color=Qt.white):
        self.insertOption(-1, widget, color)

    def insertOption(self, index, widget, color=Qt.white):
        if index < 0:
            index = self.contentLayout.count()
        self.contentLayout.insertWidget(index, widget)

        self.options.insert(index, (widget, color))

    def removeOption(self, index):
        widget, color = self.options.pop(index)
        self.contentLayout.removeWidget(widget)
        widget.deleteLater()
        self.update()

    def paintEvent(self, event):
        super().paintEvent(event)
        qp = QPainter(self)
        qp.setPen(Qt.darkGray)
        for label, color in self.options:
            geo = label.geometry()
            top = geo.y() + geo.height() / 2 - self._margin
            qp.setBrush(color)
            qp.drawEllipse(0, top, self._margin * 2, self._margin * 2)


if __name__ == '__main__':
    import sys
    app = QApplication(sys.argv)
    w = NodeFrame()
    w.addHeaderWidget(QLabel('I am a header'))
    w.addOption(QLabel('Test 1'), Qt.green)
    w.addOption(QLabel('Test 2'), Qt.white)
    w.addOption(QLineEdit('Hello'), QColor('orange'))
    w.show()
    sys.exit(app.exec_())

示例代碼截圖

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM