Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/290.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何使用三角头制作Qlabel_Python_Pyqt_Pyqt5_Qlabel - Fatal编程技术网

Python 如何使用三角头制作Qlabel

Python 如何使用三角头制作Qlabel,python,pyqt,pyqt5,qlabel,Python,Pyqt,Pyqt5,Qlabel,我试图使Qlabel看起来像Messenger中的现代聊天泡泡(圆形矩形,带有三角形尖端),如下图所示: 我已经设法使qlabel有一个锋利的边缘,但不知道如何制作尖端。问题是在拐角处插入一条三角形路径,qlabel round rect和文本应朝相反方向移动,但这样做会导致文本脱离标签区域 这是一个子类标签,包含覆盖的绘制事件和调整大小事件(在word包装中使用的调整大小可能超出了我的问题范围)>我删除了一些与颜色、字体等相关的不必要代码 class-chatLabel(qtwidts.QL

我试图使Qlabel看起来像Messenger中的现代聊天泡泡(圆形矩形,带有三角形尖端),如下图所示:

我已经设法使qlabel有一个锋利的边缘,但不知道如何制作尖端。问题是在拐角处插入一条三角形路径,qlabel round rect和文本应朝相反方向移动,但这样做会导致文本脱离标签区域

这是一个子类标签,包含覆盖的绘制事件和调整大小事件(在word包装中使用的调整大小可能超出了我的问题范围)>我删除了一些与颜色、字体等相关的不必要代码

class-chatLabel(qtwidts.QLabel):
定义初始化(self,text):
超级(chatlab,self)。\uuuuu初始化\uuuuuu(文本)
自我内容边缘(6,6,6,6)
sizePolicy=QSizePolicy(QSizePolicy.Fixed,QSizePolicy.Expanding)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
self.setSizePolicy(sizePolicy)
self.color=QtGui.QColor(#333C43)
def喷漆事件(自身,e):
p=QtGui.QPainter(自)
p、 SetRenderInt(QtGui.qPaint.Antialiasing,False)
rect=QtCore.QRectF(0,0,self.width()-1,self.height()-1)
p、 设置笔(Qt.NoPen)
path=QtGui.QPainterPath()
path.setFillRule(Qt.WindingFill)
addRoundedRect(rect,15.0,15.0)
path.addRect(self.width()-13,0,13,13)
p、 fillPath(路径,self.color)
超级(chatlab,self).paintEvent(e)
def resizeEvent(self,e):#由于Qt中有一个bug,我们需要这个。裁判:https://bugreports.qt.io/browse/QTBUG-37673
#高度宽度取决于要计算的最小尺寸,因此请在计算之前重置它
自设置最小高度(0)
#定义最小高度
self.setMinimumHeight(self.heightForWidth(self.width()))
如果self.width()>256:
self.setWordWrap(True)
自设置最小宽度(128)
超级(chatLabel,self).resizeEvent(e)
这是上述子分类标签的结果

我怎样才能达到我想要的样子?
注:我知道我可以用图像来做,但这需要根据文本大小缩放图像(9片)

我想我找到了解决问题的简单方法

因为问题是,如果我在右角做了一个提示,那么需要在文本中进行移位,以使包含在圆形矩形(气泡)中的文本。我们可以通过在样式表中使用填充来实现这一转变,这将使文本从角落处移位。因此,文本将显示为包含在气泡中

感谢用户9402680的回答和他的代码片段,我在其中添加了样式表行以达到所需的效果

from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
import sys
class chatLabel(QLabel):
    def __init__(self,text):
        super(chatLabel, self).__init__(text)
        self.setContentsMargins(6,6,6,6)
        sizePolicy = QSizePolicy(QSizePolicy.Fixed,QSizePolicy.Expanding )
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        self.setSizePolicy(sizePolicy)
        self.color = QColor("#333C43")
        # 17 px margin from right (to make the text included in the bubble
        # 8  px margin from left. 
        self.setStyleSheet("QLabel{padding: 0px 8px 0px 17px;}")


    def paintEvent(self, e):
        p = QPainter(self)
        p.setRenderHint(QPainter.Antialiasing, False)
        #I changed this width from - 1 to - 16 because I can't see the result good.
        rect =  QRectF(0,0,self.width()- 16,self.height()-1)
        p.setPen(Qt.NoPen)
        path = QPainterPath()
        path.setFillRule(Qt.WindingFill )
        path.addRoundedRect(rect, 15.0, 15.0)
        #I deleted this object
#        path.addRect(self.width()-13, 0, 13, 13)

        linePath = QPainterPath()
        linePath.moveTo(rect.right() + rect.width()/6 , rect.top())
        linePath.lineTo(rect.right() - rect.width()/2, rect.bottom())
        linePath.lineTo(rect.right() , rect.top() - rect.height()/3)
#        linePath.lineTo(rect.right() - rect.width()/5, rect.top() - rect.height()/2)
        path = path.united(linePath)
        #cubic bezier curve, please try this , too.
#        cubicPath =QPainterPath()
#        cubicPath.moveTo(rect.right() - 20, rect.top())
#        cubicPath.cubicTo(rect.right() - 20, rect.top() + rect.height()/2, rect.right() , rect.top() , rect.right() + 15, rect.top())
#        path = path.united(cubicPath)

        p.fillPath(path, self.color)

        super(chatLabel, self).paintEvent(e)

    def resizeEvent(self, e): #Due to a bug in Qt, we need this. ref:https://bugreports.qt.io/browse/QTBUG-37673
        #heightForWidth rely on minimumSize to evaulate, so reset it before
        self.setMinimumHeight( 0 )

        # define minimum height
        self.setMinimumHeight( self.heightForWidth( self.width() ) )
        if self.width()>256:
            self.setWordWrap(True)
            self.setMinimumWidth(128)

        super(chatLabel, self).resizeEvent(e)
def main():
    try:
        app=QApplication([])
    except Exception as e:
        print(e)
    widget = chatLabel("This is the result!")
    widget.show()
    sys.exit(app.exec_())
if __name__ == "__main__":
    main()
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *
import sys
class chatLabel(QLabel):
    def __init__(self,text):
        super(chatLabel, self).__init__(text)
        self.setContentsMargins(6,6,6,6)
        sizePolicy = QSizePolicy(QSizePolicy.Fixed,QSizePolicy.Expanding )
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        self.setSizePolicy(sizePolicy)
        self.color = QColor("#333C43")

    def paintEvent(self, e):
        p = QPainter(self)
        p.setRenderHint(QPainter.Antialiasing, False)
        #I changed this width from - 1 to - 16 because I can't see the result good.
        rect = QRectF(16,0,self.width()- 16,self.height()-1)
        p.setPen(Qt.NoPen)
        path = QPainterPath()
        path.setFillRule(Qt.WindingFill )
        path.addRoundedRect(rect, 15.0, 15.0)
        #I deleted this object
#        path.addRect(self.width()-13, 0, 13, 13)

        linePath = QPainterPath() linePath.moveTo(rect.left() - rect.width()/6 ,rect.top()) 
        linePath.lineTo(rect.left() + rect.width()/2, rect.bottom()) 
        linePath.lineTo(rect.left() , rect.top() - rect.height()/3)
#       linePath.lineTo(rect.right() - rect.width()/5, rect.top() - rect.height()/2)
        path = path.united(linePath)
        #cubic bezier curve, please try this , too.
#        cubicPath =QPainterPath()
#        cubicPath.moveTo(rect.right() - 20, rect.top())
#        cubicPath.cubicTo(rect.right() - 20, rect.top() + rect.height()/2, rect.right() , rect.top() , rect.right() + 15, rect.top())
#        path = path.united(cubicPath)

        p.fillPath(path, self.color)

        super(chatLabel, self).paintEvent(e)

    def resizeEvent(self, e): #Due to a bug in Qt, we need this. ref:https://bugreports.qt.io/browse/QTBUG-37673
        #heightForWidth rely on minimumSize to evaulate, so reset it before
        self.setMinimumHeight( 0 )

        # define minimum height
        self.setMinimumHeight( self.heightForWidth( self.width() ) )
        if self.width()>256:
            self.setWordWrap(True)
            self.setMinimumWidth(128)

        super(chatLabel, self).resizeEvent(e)
def main():
    try:
        app=QApplication([])
    except Exception as e:
        print(e)
    widget = chatLabel("This is the result!")
    widget.show()
    sys.exit(app.exec_())
if __name__ == "__main__":
    main()

我测试了它^^^但是提示非常小,如果在左边,这将起作用,因为移位文本的问题不会出现,因为提示被放在角落附近的空白区域,但这不是上面的图像所做的^^问题是,到目前为止,我们需要在不离开标签的情况下移动文本,我们将圆形矩形移动(为提示留一个边距)并且需要移动文本,但也要将其保持在圆形矩形内,而且看起来很精确。我将三角形添加到左下方…顶部或左侧不是问题,重要的是左侧,右侧提示没有问题。我再次更新。我将删除不必要的注释!