亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何確保??康?Qt 窗口具有帶有深色平臺主題的可見控件?

如何確保??康?Qt 窗口具有帶有深色平臺主題的可見控件?

Helenr 2022-05-24 16:37:39
考慮以下 PyQt 程序,import sysfrom PyQt5 import QtCore, QtWidgetsclass dockdemo(QtWidgets.QMainWindow):    def __init__(self, parent=None):        super(dockdemo, self).__init__(parent)        self.items = QtWidgets.QDockWidget("Dockable", self)        self.listWidget = QtWidgets.QListWidget()        self.listWidget.addItem("item1")        self.listWidget.addItem("item2")        self.listWidget.addItem("item3")        self.items.setWidget(self.listWidget)        self.addDockWidget(QtCore.Qt.RightDockWidgetArea, self.items)        self.setWindowTitle("Dock demo")def main():    app = QtWidgets.QApplication(sys.argv)    ex = dockdemo()    ex.show()    sys.exit(app.exec_())if __name__ == '__main__':    main()這可以正常工作并生成一個簡單的??看翱冢旱牵@不符合我的 GTK2 黑暗平臺主題。如果我通過設置強制Qt這樣做QT_QPA_PLATFORMTHEME=gtk2,我會得到這個:停靠窗口的控件幾乎與背景顏色相同,因此很難看到。C++ 中的 GNU Octave 在平臺主題中正確顯示了它自己的停靠小部件控件:Octave 的??啃〔考诓皇褂孟到y主題時也會顯示正確的控件。我懷疑這可能是由于它在這里設置的一些 CSS,但我不知道具體是什么:http ://hg.savannah.gnu.org/hgweb/octave/file/6d0585c8ee11/libgui/src/octave-dock -widget.cc#l123難道我做錯了什么?感覺就像一個錯誤,Qt 沒有正確設置停靠窗口控件的顏色,除非你做一些額外的事情(以及額外的可能是什么,我還不知道)。
查看完整描述

2 回答

?
慕少森

TA貢獻2019條經驗 獲得超9個贊

感謝這里的另一個答案,我有一個完整的解決方案來解決我原來的問題。


看起來 Qt 只是簡單地硬編碼這些圖標而不考慮主題,但這很容易修復。


首先,我們使用相對亮度來決定顏色是否明亮,


def is_dark(qt_colour):

    r, g, b = qt_colour.red(), qt_colour.green(), qt_colour.blue()

    luminance = (0.2126*r + 0.7152*g + 0.0722*b)/256


    return luminance < 0.5

在其源代碼樹中找到。我們將這些圖標放在img/子目錄/子文件夾中。


然后,我們獲取小部件的背景顏色,


        bg_colour = self.items.palette().color(QtGui.QPalette.Background)

根據該顏色,我們將 CSS 設置為使用淺色或深色圖標集:


        if is_dark(bg_colour):

            self.items.setStyleSheet(

                """

                QDockWidget

                {

                  titlebar-close-icon: url(img/widget-close-light.svg);

                  titlebar-normal-icon: url(img/widget-undock-light.svg);

                }

                """

            )

        else:

            self.items.setStyleSheet(

                """

                QDockWidget

                {

                  titlebar-close-icon: url(img/widget-close.svg);

                  titlebar-normal-icon: url(img/widget-undock.svg);

                }

                """

            )

這會在淺色和深色主題中產生正確的圖標!

http://img1.sycdn.imooc.com//628c99af0001f97705160242.jpg

現在完整的代碼如下所示:


import sys

from PyQt5 import QtCore, QtWidgets, QtGui



def is_dark(qt_colour):

    r, g, b = qt_colour.red(), qt_colour.green(), qt_colour.blue()

    luminance = (0.2126*r + 0.7152*g + 0.0722*b)/256


    return luminance < 0.5



class dockdemo(QtWidgets.QMainWindow):

    def __init__(self, parent=None):

        super(dockdemo, self).__init__(parent)


        self.items = QtWidgets.QDockWidget("Dockable", self)

        self.listWidget = QtWidgets.QListWidget()

        self.listWidget.addItem("item1")

        self.listWidget.addItem("item2")

        self.listWidget.addItem("item3")


        self.items.setWidget(self.listWidget)

        self.addDockWidget(QtCore.Qt.RightDockWidgetArea, self.items)

        bg_colour = self.items.palette().color(QtGui.QPalette.Background)

        if is_dark(bg_colour):

            self.items.setStyleSheet(

                """

                QDockWidget

                {

                  titlebar-close-icon: url(img/widget-close-light.svg);

                  titlebar-normal-icon: url(img/widget-undock-light.svg);

                }

                """

            )

        else:

            self.items.setStyleSheet(

                """

                QDockWidget

                {

                  titlebar-close-icon: url(img/widget-close.svg);

                  titlebar-normal-icon: url(img/widget-undock.svg);

                }

                """

            )

        self.setWindowTitle("Dock demo")



def main():

    app = QtWidgets.QApplication(sys.argv)

    ex = dockdemo()

    ex.show()

    sys.exit(app.exec_())



if __name__ == '__main__':

    main()


查看完整回答
反對 回復 2022-05-24
?
慕俠2389804

TA貢獻1719條經驗 獲得超6個贊

不幸的是,Linux 默認的 Qt Fusion 樣式停靠圖標被硬編碼為 XPM 格式的圖像QFusionStyle(也是QCommonStyle其中的后備)。而且它們從不著色以匹配主題。許多“標準”圖標都是這樣,但許多是彩色/不透明的,因此背景并沒有太大的區別。


要覆蓋它們,您需要使用 CSS 或自定義QProxyStyle.


您可以從鏈接到的示例中看到它是如何在 CSS 中完成的。


QDockWidget

{

  titlebar-close-icon: url(close.svg);

  titlebar-normal-icon: url(restore.svg);

}

自定義 QStyle 涉及更多...


class AppStyle : public QProxyStyle

{

  public:

    using QProxyStyle::QProxyStyle;


    QIcon standardIcon(StandardPixmap standardIcon, const QStyleOption *option = nullptr, const QWidget *widget = nullptr) const override

    {

      switch (standardIcon) {

        case SP_TitleBarNormalButton:

          return QIcon("restore.svg");


        case SP_TitleBarCloseButton:

        case SP_DockWidgetCloseButton:

          return QIcon("close.svg");


        default:

          return baseStyle()->standardIcon(standardIcon, option, widget);

      }

    }


    QPixmap standardPixmap(StandardPixmap stdPixmap, const QStyleOption *option = nullptr, const QWidget *widget = nullptr) const override

    {

      switch (stdPixmap) {

        case SP_TitleBarNormalButton:

        case SP_TitleBarCloseButton:

        case SP_DockWidgetCloseButton:

          return standardIcon(stdPixmap, option, widget).pixmap(option->rect.size());


        default:

          return baseStyle()->standardPixmap(stdPixmap, option, widget);

      }

    }


};

在這兩種情況下,您都需要知道以某種方式使用的主題(例如,它是黑暗的)。您將為每個主題使用不同的(或動態的)CSS,或者您的自定義QProxyStyle將返回正確的基本顏色圖標。例如,在 C++ 中,您甚至可以確定當前的調色板背景是否為暗(低顏色值),然后基于此返回不同的圖標。


PS 是的,它可能被認為是一個“錯誤”或缺陷,Qt 沒有為黑暗系統主題“自動”處理這個問題——無論桌面主題如何,嘗試將應用程序皮膚設置為黑暗時也很煩人。但是c'est la vie。


PPS 哎呀,剛剛意識到我為 Python 問題提供了一個 C++ 示例......我不使用 Python 和 Qt,所以恐怕這是我能做的最好的。


查看完整回答
反對 回復 2022-05-24
  • 2 回答
  • 0 關注
  • 242 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號