スポンサーサイト

    上記の広告は1ヶ月以上更新のないブログに表示されています。
    新しい記事を書く事で広告が消せます。

    スタイルシートを子供に反映したくないでござる!!!

     Qtネタ。

     Qtではスタイルシートによって簡単に外観を変更できてメッチャ便利です。
     スタイルシート自体はウェブのCSSに基本的には準じていて、またサンプルコードもあるので非常に取っ付き易くて素晴らしいですな。


     そんなお手軽便利なスタイルシートですが、このスタイルシートを設定したウィジェットの子は、親のスタイルシートを引き継ぐように設計されています。
     基本的にはコレで問題ないのですが、当然そうでもない場合も多々あります。

     そんな時にはどうすればいいのか探したところ、結構簡単に出来そうだったのでメモとして残しておきます。
     って事でまずは普通にスタイルシートを使った場合。
     QFrameで枠を作り、その下にQLabelで文字を配置します。そして枠に色を付けたかったのでスタイルシートでQFrameを変更。
     しかし、それをやると・・・
     って事でまずはソースコードから。
    # -*- coding:utf-8 -*-
    import sys
    from PySide import QtGui, QtCore
    
    class NamedTestFrame(QtGui.QFrame):
        '''文字を羅列したQFrameオブジェクト。'''
        def __init__(self, parent=None):
            super(NamedTestFrame, self).__init__(parent)
            # スタイルシートを適応する。
            self.setStyleSheet(
                'QFrame{'
                'background:#404040; color:#f0f0f0;'
                'font-family:arial;'
                'border:1px solid #000000; border-radius:8px;'
                '}'
            )
    
            # 文字を表示するためのQLabelを2つ用意する。---------------------------
            # それぞれにはスタイルシートで文字の大きさを指定する。
            labelA = QtGui.QLabel('SSS Test Frame')
            labelA.setStyleSheet('QLabel{font-size : 24px;}')
            labelB = QtGui.QLabel(
                'Decolated text.\n  Line1\n  Line2\n  Line3\n  Line4'
            )
            labelB.setStyleSheet('QLabel{font-size : 12px;}')
            # ---------------------------------------------------------------------
    
            layout = QtGui.QVBoxLayout(self)
            layout.addWidget(labelA)
            layout.addWidget(labelB)
    
    
    class MainWidget(QtGui.QWidget):
        '''メインとなるウィジェット。(親)'''
        def __init__(self, parent=None):
            super(MainWidget, self).__init__(parent)
            self.setStyleSheet(
                'QWidget{background:#606060;}'
            )
    
            frameA = NamedTestFrame(self)
            frameB = NamedTestFrame(self)
    
            layout = QtGui.QHBoxLayout(self)
            layout.addWidget(frameA)
            layout.addWidget(frameB)
    
    
    # メインルーチン。
    if __name__ == '__main__':
        app = QtGui.QApplication(sys.argv)
        widget = MainWidget()
        widget.show()
        
        sys.exit(app.exec_())
    
     文字を囲ってるQFrameに枠が欲しかったので、11行目のところでスタイルシートを使って枠を作成!

    qtStyleSheet001.png  ・・・したものの、その子となってるQLabelもQFrameを継承したクラスなので、冒頭で説明したように親のスタイルシートを引き継いでしまって、文字ごとに枠が出現(´Д`|||) ドヨーン
     このままでは宜しくないので何とかしたいですが、わざわざ子供であるQLabel2つにスタイルシートを設定するのもなぁ・・・
     スタイルシートを変数で定義してしまえば別段管理は問題ないのですが、何かひっかかる・・・(´ε`;)ウーン…

     ってことで何か手はないのかと調べてみたら、ちゃんとありましたヨ。
     それは
    QWidget.setObjectName('オブジェクト名')
    およびスタイルシート内で
    #オブジェクト名
    を使用。
    
     まずは子階層にまでスタイルシートの影響を及ぼしたくないQWidget(及び派生クラス)に
    setObjectName
    
     メソッドを使用してオブジェクト名をつけます。この名前はデフォルトでは空文字列が入っていますが、ここに任意の名前を指定します。
     今回は"MainFrame"と言う名前を入れてみます。

     そしてこの名前を使用してスタイルシートでスタイルを適応します。
     サンプルコードの11行目"QFrame"のところでQFrameを指定する代わりに先ほど指定した名前を使用して
    #MainFrame
    
    と指定します。

    9行目から16行目をこんな感じに変更します。
            # オブジェクト名を設定する。
            self.setObjectName('MainFrame')
            # スタイルシートを適応する。
            self.setStyleSheet(
                '#MainFrame{'
                'background:#404040; color:#f0f0f0;'
                'font-family:arial;'
                'border:1px solid #000000; border-radius:8px;'
                '}'
            )
    
     しかしこれで確かに子階層には影響がなくなりましたが、まったく影響がなくなってしまったのでQFrameの枠の中に独立したQLabelがある感じになってしまいました・・・
     これはこれで困る・・・

     って事で、setStyleSheetを行う時に、子階層まで影響を及ぼしたいものをQFrameで指定し、枠だけ独自にしたい部分を#MainFrameで指定します。  って事でこれで完成~。
    # -*- coding:utf-8 -*-
    import sys
    from PySide import QtGui, QtCore
    
    class NamedTestFrame(QtGui.QFrame):
        '''文字を羅列したQFrameオブジェクト。'''
        def __init__(self, parent=None):
            super(NamedTestFrame, self).__init__(parent)
            # オブジェクト名を設定する。
            self.setObjectName('MainFrame')
            # スタイルシートを適応する。
            self.setStyleSheet(
                # QFrame共通のスタイルシート
                'QFrame{'
                'background:#404040; color:#f0f0f0;'
                'font-family:arial;'
                '}'
    
                # このオブジェクトのみに適応させるためのスタイルシート。
                '#MainFrame{'
                'border:1px solid #000000; border-radius:8px;'
                '}'
            )
    
            # 文字を表示するためのQLabelを2つ用意する。---------------------------
            # それぞれにはスタイルシートで文字の大きさを指定する。
            labelA = QtGui.QLabel('SSS Test Frame')
            labelA.setStyleSheet('QLabel{font-size : 24px;}')
            labelB = QtGui.QLabel(
                'Decolated text.\n  Line1\n  Line2\n  Line3\n  Line4'
            )
            labelB.setStyleSheet('QLabel{font-size : 12px;}')
            # ---------------------------------------------------------------------
    
            layout = QtGui.QVBoxLayout(self)
            layout.addWidget(labelA)
            layout.addWidget(labelB)
    
    
    class MainWidget(QtGui.QWidget):
        '''メインとなるウィジェット。(親)'''
        def __init__(self, parent=None):
            super(MainWidget, self).__init__(parent)
            self.setStyleSheet(
                'QWidget{background:#606060;}'
            )
    
            frameA = NamedTestFrame(self)
            frameB = NamedTestFrame(self)
    
            layout = QtGui.QHBoxLayout(self)
            layout.addWidget(frameA)
            layout.addWidget(frameB)
    
    
    # メインルーチン。
    if __name__ == '__main__':
        app = QtGui.QApplication(sys.argv)
        widget = MainWidget()
        widget.show()
        
        sys.exit(app.exec_())
    
     これで特定のパーツの、特定のスタイルだけ設定できるようになりました。
    qtStyleSheet002.png
     因みにオブジェクト名は識別子なので、複数のオブジェクトで被ってても大丈夫です!!


     これでUIの外観のカスタマイズがさらに楽になりますね(*´∀`*)
    スポンサーサイト

    コメントの投稿

    非公開コメント

    プロフィール

    Eske

    Author:Eske
    萌えイラストレーターを目指す3DCGイラストレーター。
    現在ポケモンカードゲーム、ガンダムトライエイジ、ガンダムコンクエスト、妖怪ウォッチとりつきカードゲームなどで3DCGを使用したイラストレーターとして参加中。

    主にここでは日々気づいたメモなんかを残してます。
    イラストのお仕事も受け付けております。ココのメールアドレスからご連絡できますので、お気軽にご相談下さい。

    最新記事
    最新コメント
    カテゴリ
    最新トラックバック
    月別アーカイブ
    検索フォーム
    リンク
    QRコード
    QR
    上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。