Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting black border on white text possible?

Tags:

python

pyqt

pyqt5

So I have a graph tool of sorts using a PyQt5 gui, and giving the user the ability to color nodes and name them. But you can imagine that depending on what color you color the nodes, the text can be illegible. So if there was a way to get a black border on a QFont, then I can have text white and have it show up well over anything. Is this possible given the framework?

I'm also open to any solution that solves the problem of being able to read text over any color as well. Thank you.

Edit:

from PyQt5 import QtGui, QtWidgets


class MyPushButton(QtWidgets.QPushButton):

    def __init__(self, text):
        super(MyPushButton, self).__init__()
        self.setFixedHeight(50)

        self.font = QtGui.QFont()
        self.setupFont()
        self.setFont(self.font)

        self.setStyleSheet('color: white; background-color: yellow')
        self.setText(text)
        self.clicked.connect(self.change_color)

    def change_color(self):
        color = QtWidgets.QColorDialog.getColor()
        if color.isValid():
            self.setStyleSheet('color: white;background-color:' + color.name())

    def setupFont(self):
        self.font.setFamily('Palatino')
        self.font.setPointSize(20)
        # some other font manipulations


if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)

    widget = QtWidgets.QWidget()
    layout = QtWidgets.QVBoxLayout()

    push1 = MyPushButton('test text 1')
    layout.addWidget(push1)

    push2 = MyPushButton('test text 2')
    layout.addWidget(push2)

    widget.setLayout(layout)
    widget.show()
    sys.exit(app.exec_())

I want:

enter image description here

like image 485
Ned U Avatar asked Oct 19 '25 14:10

Ned U


1 Answers

One possible solution is to use QML to create that effect, and for you to use it with classic widgets you should use QQuickWidget as shown below:

main.qml

import QtQuick 2.9
import QtQuick.Controls 2.4

Button {
    id: control
    property color color: "white"
    property color _color:  down ? Qt.lighter(color, 1.1):  color
    property color light_color: Qt.lighter(control._color, 1.1)
    property color dark_color: Qt.darker(control._color, 1.1)
    contentItem: Text {
        text: control.text
        font: control.font
        color: "white"
        style: Text.Outline
        styleColor: "black"
        horizontalAlignment: Text.AlignHCenter
        verticalAlignment: Text.AlignVCenter
    }

    background: Rectangle {
        opacity: enabled ? 1 : 0.3
        border.width: 0.7
        border.color: "gray"
        radius: 2
        gradient: Gradient {
            GradientStop { position: 0 ; color: control.pressed ? control._color : control.light_color }
            GradientStop { position: 1 ; color: control.pressed ? control.dark_color : control._color }
        }
    }
    onClicked: obj.clicked()
}

main.py

from PyQt5 import QtCore, QtGui, QtWidgets, QtQuickWidgets

class ButtonQMl(QtQuickWidgets.QQuickWidget):
    clicked = QtCore.pyqtSignal()

    def __init__(self, parent=None):
        super(ButtonQMl, self).__init__(parent)
        self.setSource(QtCore.QUrl.fromLocalFile("main.qml"))
        self.setResizeMode(QtQuickWidgets.QQuickWidget.SizeRootObjectToView)
        self.setSizePolicy(QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Fixed)
        self.engine().rootContext().setContextProperty("obj", self)
        self.setFixedHeight(50)

    def text(self):
        return self.rootObject().property("text") if self.rootObject() else  ""

    def setText(self, text):
        if self.rootObject() and self.text() != text:
            self.rootObject().setProperty("text", text)

    def color(self):
        return self.rootObject().property("color") if self.rootObject() else  ""

    def setColor(self, color):
        color = QtGui.QColor(color)
        if self.rootObject() and self.color() != color:
            self.rootObject().setProperty("color", color)

    def font(self):
        return self.rootObject().property("font") if self.rootObject() else  ""

    def setFont(self, font):
        if self.rootObject() and self.font() != font:
            self.rootObject().setProperty("font", font)


class MyButton(ButtonQMl):
    def __init__(self, parent=None):
        super(MyButton, self).__init__(parent)
        self.clicked.connect(self.change_color)
        self.setupFont()

    def change_color(self):
        color = QtWidgets.QColorDialog.getColor()
        if color.isValid():
            self.setColor(color)

    def setupFont(self):
        fnt = self.font()
        fnt.setFamily('Palatino')
        fnt.setPointSize(20)
        self.setFont(fnt)

    def mousePressEvent(self, event):
        print("event: ", event)
        super(MyButton, self).mousePressEvent(event)

if __name__ == '__main__':
    import sys
    app = QtWidgets.QApplication(sys.argv)

    w = QtWidgets.QWidget()
    lay = QtWidgets.QVBoxLayout(w)
    btn1 = MyButton()
    btn1.setText("Hello World");
    btn1.setColor(QtCore.Qt.yellow)

    btn2 = QtWidgets.QPushButton("Click me")
    btn2.setFixedHeight(50)
    btn2.setStyleSheet("color: white; background-color: yellow")

    lay.addWidget(btn1)
    lay.addWidget(btn2)

    w.show()
    sys.exit(app.exec_())

enter image description here

like image 155
eyllanesc Avatar answered Oct 22 '25 02:10

eyllanesc