Белая рамка на прозрачном изображении QSplashScreen в PyQt - PullRequest
3 голосов
/ 01 декабря 2011

Google, хотя я и пытался, я не могу понять, как избавиться от белой границы, которую я обхожу вокруг png, которую я обслуживаю QSplashScreen.

Я видел эта статья , но я не знаю, как перевести это на PyQt, или даже это то, что я хочу.

Я даже пытался установить черно-белую маску отдельно, что дало результат низкого качества с множеством точек повсюду.

Кто-нибудь разобрался с волшебным полупрозрачным / полупрозрачным SplashScreen, которыйВы также можете передать текстовые данные, аля команда showMessage?Заранее спасибо.

Я должен упомянуть, что это также и Windows 7.

Ниже приведены тестовые PNG, которые я использую в качестве заставки, а также получающаяся в результате уродливая белая рамка.Я понял:

Splash Image Result in Windows 7

Альтернативный метод предоставления черно-белой альфы через QBitmap дает этот более близкий, но более уродливый пример со странными точками.Код и изображения приведены ниже.

    splash_pix = QPixmap(":/images/images/PyQtSplash.png")
    splash = QSplashScreen(splash_pix, Qt.WindowStaysOnTopHint)
    splash.setMask(QBitmap(QPixmap(":/images/images/PyQtSplashAlpha.jpg")))

Splash Alpha QBitmap Result

1 Ответ

3 голосов
/ 01 декабря 2011

Пока вы используете изображение с чистыми прозрачными областями, необходимо только передать его маску на QSplashScreen.setMask.

ЭтоСценарий работает для меня в Linux так:

from PyQt4 import QtGui, QtCore

def show_splash(path):
    image = QtGui.QPixmap(path)
    splash = QtGui.QSplashScreen(image)
    splash.setAttribute(QtCore.Qt.WA_DeleteOnClose)
    splash.setMask(image.mask())
    font = QtGui.QFont(splash.font())
    font.setPointSize(font.pointSize() + 5)
    splash.setFont(font)
    splash.show()
    QtGui.QApplication.processEvents()
    for count in range(1, 6):
        splash.showMessage(splash.tr('Processing %1...').arg(count),
                           QtCore.Qt.AlignBottom | QtCore.Qt.AlignLeft,
                           QtCore.Qt.white)
        QtGui.QApplication.processEvents()
        QtCore.QThread.msleep(1000)

if __name__ == '__main__':

    import sys
    app = QtGui.QApplication(sys.argv)
    show_splash(sys.argv[1])
    app.quit()

РЕДАКТИРОВАТЬ

Этот пользовательский класс SplashScreen должен давать разумные результаты как в Linux, так и в Windows:

from PyQt4 import QtGui, QtCore

class SplashScreen(QtGui.QWidget):
    def __init__(self, pixmap):
        QtGui.QWidget.__init__(self)
        self._pixmap = pixmap
        self._message = QtCore.QString()
        self._color = QtGui.QColor.black
        self._alignment = QtCore.Qt.AlignLeft
        self.setWindowFlags(QtCore.Qt.FramelessWindowHint |
                            QtCore.Qt.WindowStaysOnTopHint)
        self.setAttribute(QtCore.Qt.WA_TranslucentBackground)
        self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
        self.setFixedSize(self._pixmap.size())
        self.setMask(self._pixmap.mask())

    def clearMessage(self):
        self._message.clear()
        self.repaint()

    def showMessage(self, message, alignment=QtCore.Qt.AlignLeft,
                                   color=QtGui.QColor.black):
        self._message = QtCore.QString(message)
        self._alignment = alignment
        self._color = color
        self.repaint()

    def paintEvent(self, event):
        textbox = QtCore.QRect(self.rect())
        textbox.setRect(textbox.x() + 5, textbox.y() + 5,
                        textbox.width() - 10, textbox.height() - 10)
        painter = QtGui.QPainter(self)
        painter.drawPixmap(self.rect(), self._pixmap)
        painter.setPen(QtGui.QColor(self._color))
        painter.drawText(textbox, self._alignment, self._message)

    def mousePressEvent(self, event):
        self.hide()

def show_splash(path):
    image = QtGui.QPixmap(path)
    splash = SplashScreen(image)
    font = QtGui.QFont(splash.font())
    font.setPointSize(font.pointSize() + 5)
    splash.setFont(font)
    splash.show()
    QtGui.QApplication.processEvents()
    for count in range(1, 6):
        splash.showMessage(splash.tr('Processing %1...').arg(count),
                           QtCore.Qt.AlignCenter, QtCore.Qt.white)
        QtGui.QApplication.processEvents()
        QtCore.QThread.msleep(1000)
    splash.hide()
    splash.close()

if __name__ == '__main__':

    import sys
    app = QtGui.QApplication(sys.argv)
    show_splash(sys.argv[1])
    app.quit()
...