rikai-mpv icon indicating copy to clipboard operation
rikai-mpv copied to clipboard

Stroke on subs

Open TingTingin opened this issue 3 years ago • 3 comments

How did you get the stroke on the subs in QTextedit I have this code and im trying to add a stroke to qtextedit not sure how you did it on yours with the qt window

from PyQt5.QtWidgets import QApplication, QVBoxLayout, QWidget, QTextEdit, QGraphicsDropShadowEffect
from PyQt5 import QtGui
from PyQt5.QtCore import QPointF, Qt


class Subs(QTextEdit):
    def __init__(self):
        super().__init__()
        self.setMouseTracking(True)
        self.setMaximumHeight(50)
        self.setText("これはぺんだ これはぺんだ これはぺんだ これはぺんだ これはぺんだ これはぺんだ")
        self.setStyleSheet("background-color: rgba(255,255,255,0); border: 0; font-size: 40px; font-family: 'MIGU 1M'; color: white;")

        shadow = QGraphicsDropShadowEffect()
        shadow.setXOffset(0)
        shadow.setYOffset(0)
        shadow.setColor(QtGui.QColor.fromRgb(0, 0, 0))
        shadow.setBlurRadius(10)
        shadow.sourcePixmap()
        self.setGraphicsEffect(shadow)

        self.setAlignment(Qt.AlignCenter)
        self.setVerticalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff)
        self.setHorizontalScrollBarPolicy(Qt.ScrollBarPolicy.ScrollBarAlwaysOff)
        self.setLineWrapMode(QTextEdit.LineWrapMode.NoWrap)

    def mouseMoveEvent(self, event):
        if type(event) == QtGui.QMouseEvent:
            point_position = event.pos()  # this is relative coordinates in the QTextEdit
            char_index = self.document().documentLayout().hitTest(QPointF(point_position.x(), point_position.y()), Qt.HitTestAccuracy.ExactHit)
            print(char_index)


class Window(QWidget):
    def __init__(self):
        global text
        super(Window, self).__init__()
        self.setFixedWidth(1920)
        self.move(0, 960)
        self.setMouseTracking(True)
        self.setWindowFlag(Qt.FramelessWindowHint)
        self.setAttribute(Qt.WA_TranslucentBackground)
        self.setWindowFlag(Qt.WindowStaysOnTopHint)
        vbox = QVBoxLayout()
        self.setLayout(vbox)

        vbox.addWidget(Subs())
        Subs()
        self.setLayout(vbox)


app = QApplication(sys.argv)
window = Window()
window.show()
app.installEventFilter(window)
sys.exit(app.exec())


TingTingin avatar Mar 25 '22 02:03 TingTingin

Hello, by stroke do you mean the black part surrounding the text in white, like outline?

If so, you are interested in this part: https://github.com/fxmarty/rikai-mpv/blob/422fb1085b3e20b4790d0bb554cafe095514789f/subtitles_popup_graphics.py#L456

    def paintEvent(self, event):
        # this is just a trick to avoid an infinite loop due to the painting of the
        # outline, as the line `my_cursor.select(QTextCursor.SelectionType.Document)`
        # triggers a recursive call to `paintEvent`
        self.render_ready += 1
        
        if self.render_ready > 3 and self.no_popup:
            self.setUpdatesEnabled(False)
        
        # Showing the outline is really slow (at times, more than 100 ms) and
        # we do not want to do it when the user shows popups, as it slows everything down.
        # Ideally, it could probably be in a separate thread.
        if not self.already_in:
            painter = QPainter(self.viewport())
            
            my_cursor = self.textCursor()
            my_char_format = my_cursor.charFormat()
            
            my_char_format.setTextOutline(self.outline_pen)
            
            my_cursor.select(QTextCursor.SelectionType.Document)
            my_cursor.mergeCharFormat(my_char_format)
            
            self.document().drawContents(painter)
            
            my_char_format.setTextOutline(self.transparent_pen)
            my_cursor.mergeCharFormat(my_char_format)
        
        super().paintEvent(event)

Note that at the time I found this solution to show a nice outline, but it is very subideal as it redefines paintEvent and would repaint the outline every time it is called. Not sure why I put it in there.

fxmarty avatar Mar 25 '22 09:03 fxmarty

Thx I think ultimately for me its probably just better to use a drop shadow to highlight the text

One solution I was thinking of though with the stroke would be to have a copy of the sub layer underneath the main sub layer and change the color and font weight of the duplicate to create a stroke I couldn't really figure it out though maybe its a better solution for you situation? anyway thanks for the help

TingTingin avatar Mar 25 '22 14:03 TingTingin

I should look into it sometime again, I remember it was quite hacky

fxmarty avatar Oct 26 '22 20:10 fxmarty