各レイアウトの幅を自由に変更できるようになる QSplitter についてです。
色々とクセがあってこれまで使う度に1から調べることになっていたので、
いい加減ちゃんとまとめておこうと思います。
基本的な使い方
- QSplitter を作ってレイアウトに設置
- QSplitter に入れたいウィジェットを作る
- QSplitter に配置
というのが最も基本的な使い方です。
import sys
from PySide2 import QtWidgets, QtCore
from PySide2.QtCore import Qt
class MainWindow(QtWidgets.QMainWindow):
"""
QSplitter
"""
def __init__(self):
super(MainWindow, self).__init__()
# ウィンドウサイズの指定
self.resize(QtCore.QSize(600, 300))
wrapper = QtWidgets.QWidget()
self.setCentralWidget(wrapper)
#
# ルートエリアの作成と設置
#
root_area = QtWidgets.QVBoxLayout()
wrapper.setLayout(root_area)
#
# スプリッターの作成
#
splitter = QtWidgets.QSplitter(Qt.Horizontal)
root_area.addWidget(splitter)
#
# ウィジェットの作成
#
plane_text_1 = QtWidgets.QPlainTextEdit()
plane_text_2 = QtWidgets.QPlainTextEdit()
#
# スプリッターへウィジェットを設置
#
splitter.addWidget(plane_text_1)
splitter.addWidget(plane_text_2)
def launch_from_standalone():
"""
スタンドアロン用のウィンドウ起動
"""
standalone_app = QtWidgets.QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(standalone_app.exec_())
if __name__ == '__main__':
launch_from_standalone()
横へ分割
splitter = QtWidgets.QSplitter(Qt.Horizontal)
上のコードは 横方向へ分割しています。
QSplitter の引数に Qt.Horizontal
を渡します。
縦へ分割
splitter = QtWidgets.QSplitter(Qt.Vertical)
Qt.Horizontal
だった部分を QtVertical
に変更することで縦に分割できます。
コード全文
import sys
from PySide2 import QtWidgets, QtCore
from PySide2.QtCore import Qt
class MainWindow(QtWidgets.QMainWindow):
"""
QSplitter
"""
def __init__(self):
super(MainWindow, self).__init__()
# ウィンドウサイズの指定
self.resize(QtCore.QSize(600, 300))
wrapper = QtWidgets.QWidget()
self.setCentralWidget(wrapper)
#
# ルートエリアの作成と設置
#
root_area = QtWidgets.QVBoxLayout()
wrapper.setLayout(root_area)
#
# スプリッターの作成
#
splitter = QtWidgets.QSplitter(Qt.Vertical)
root_area.addWidget(splitter)
#
# ウィジェットの作成
#
plane_text_1 = QtWidgets.QPlainTextEdit()
plane_text_2 = QtWidgets.QPlainTextEdit()
#
# スプリッターへウィジェットを設置
#
splitter.addWidget(plane_text_1)
splitter.addWidget(plane_text_2)
def launch_from_standalone():
"""
スタンドアロン用のウィンドウ起動
"""
standalone_app = QtWidgets.QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(standalone_app.exec_())
if __name__ == '__main__':
launch_from_standalone()
スクロールエリアはデフォルトでついてない
デフォルトで QScrollArea
はついていません。
そのため、サイズを固定したウィジェットを入れた場合は
スクロールせずに折り畳まれてしまいます。
サンプルコード
import sys
from PySide2 import QtWidgets, QtCore
from PySide2.QtCore import Qt
class MainWindow(QtWidgets.QMainWindow):
"""
QSplitter
"""
def __init__(self):
super(MainWindow, self).__init__()
# ウィンドウサイズの指定
self.resize(QtCore.QSize(600, 300))
wrapper = QtWidgets.QWidget()
self.setCentralWidget(wrapper)
#
# ルートエリアの作成と設置
#
root_area = QtWidgets.QVBoxLayout()
wrapper.setLayout(root_area)
#
# スプリッターの作成
#
splitter = QtWidgets.QSplitter(Qt.Horizontal)
root_area.addWidget(splitter)
#
# ウィジェットの作成 とレイアウトの設置
#
widget_a = QtWidgets.QWidget()
widget_b = QtWidgets.QWidget()
splitter.addWidget(widget_a)
splitter.addWidget(widget_b)
vbox_a = QtWidgets.QVBoxLayout(widget_a)
vbox_b = QtWidgets.QVBoxLayout(widget_b)
#
# ボタンの作成と設置
#
for i in range(5):
btn_a = QtWidgets.QPushButton('btn_A_{}'.format(i))
btn_b = QtWidgets.QPushButton('btn_B_{}'.format(i))
for btn in [btn_a, btn_b]:
btn.setFixedSize(300, 30)
vbox_a.addWidget(btn_a)
vbox_b.addWidget(btn_b)
def launch_from_standalone():
"""
スタンドアロン用のウィンドウ起動
"""
standalone_app = QtWidgets.QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(standalone_app.exec_())
if __name__ == '__main__':
launch_from_standalone()
スクロールエリアを入れた分割
スクロールエリアを入れることでちゃんとスクロールしてくれるようになります。
#
# スクロールエリアの作成
#
scroll_area_a = QtWidgets.QScrollArea()
scroll_area_b = QtWidgets.QScrollArea()
scroll_area_a.setWidgetResizable(True)
scroll_area_b.setWidgetResizable(True)
widget_a = QtWidgets.QWidget()
widget_b = QtWidgets.QWidget()
scroll_area_a.setWidget(widget_a)
scroll_area_b.setWidget(widget_b)
scroll_vbox_a = QtWidgets.QVBoxLayout(widget_a)
scroll_vbox_b = QtWidgets.QVBoxLayout(widget_b)
#
# スプリッターへスクロールエリアを設置
#
splitter.addWidget(scroll_area_a)
splitter.addWidget(scroll_area_b)
コード全文
import sys
from PySide2 import QtWidgets, QtCore
from PySide2.QtCore import Qt
class MainWindow(QtWidgets.QMainWindow):
"""
QSplitter
"""
def __init__(self):
super(MainWindow, self).__init__()
# ウィンドウサイズの指定
self.resize(QtCore.QSize(600, 300))
wrapper = QtWidgets.QWidget()
self.setCentralWidget(wrapper)
#
# ルートエリアの作成と設置
#
root_area = QtWidgets.QVBoxLayout()
wrapper.setLayout(root_area)
#
# スプリッターの作成
#
splitter = QtWidgets.QSplitter(Qt.Horizontal)
root_area.addWidget(splitter)
#
# スクロールエリアの作成
#
scroll_area_a = QtWidgets.QScrollArea()
scroll_area_b = QtWidgets.QScrollArea()
scroll_area_a.setWidgetResizable(True)
scroll_area_b.setWidgetResizable(True)
widget_a = QtWidgets.QWidget()
widget_b = QtWidgets.QWidget()
scroll_area_a.setWidget(widget_a)
scroll_area_b.setWidget(widget_b)
scroll_vbox_a = QtWidgets.QVBoxLayout(widget_a)
scroll_vbox_b = QtWidgets.QVBoxLayout(widget_b)
#
# スプリッターへスクロールエリアを設置
#
splitter.addWidget(scroll_area_a)
splitter.addWidget(scroll_area_b)
#
# ボタンの作成と設置
#
for i in range(5):
btn_a = QtWidgets.QPushButton('btn_A_{}'.format(i))
btn_b = QtWidgets.QPushButton('btn_B_{}'.format(i))
for btn in [btn_a, btn_b]:
btn.setFixedSize(300, 30)
scroll_vbox_a.addWidget(btn_a)
scroll_vbox_b.addWidget(btn_b)
def launch_from_standalone():
"""
スタンドアロン用のウィンドウ起動
"""
standalone_app = QtWidgets.QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(standalone_app.exec_())
if __name__ == '__main__':
launch_from_standalone()
QScrollArea を入れた QWidget をクラス化
スプリッターを多用する場合は
QScrollArea を入れた QWidget をクラス化しておくと便利です。
下記の文は上のものと全く同じ結果になりますが、コードがシンプルになるので保守がしやすくなります。
class ScrollWidget(QtWidgets.QScrollArea):
"""
スクロールエリアを入れたウィジェット
"""
def __init__(self):
super(ScrollWidget, self).__init__()
self.setWidgetResizable(True)
#
# ウィジェット / レイアウトの設置
#
widget = QtWidgets.QWidget()
self.setWidget(widget)
self.vbox = QtWidgets.QVBoxLayout(widget)
コード全文
import sys
from PySide2 import QtWidgets, QtCore
from PySide2.QtCore import Qt
class MainWindow(QtWidgets.QMainWindow):
"""
QSplitter
"""
def __init__(self):
super(MainWindow, self).__init__()
# ウィンドウサイズの指定
self.resize(QtCore.QSize(600, 300))
wrapper = QtWidgets.QWidget()
self.setCentralWidget(wrapper)
#
# ルートエリアの作成と設置
#
root_area = QtWidgets.QVBoxLayout()
wrapper.setLayout(root_area)
#
# スプリッターの作成
#
splitter = QtWidgets.QSplitter(Qt.Horizontal)
root_area.addWidget(splitter)
#
# スクロールウィジェットの作成
#
scroll_widget_a = ScrollWidget()
scroll_widget_b = ScrollWidget()
#
# スプリッターへスクロールエリアを設置
#
splitter.addWidget(scroll_widget_a)
splitter.addWidget(scroll_widget_b)
#
# ボタンの作成と設置
#
for i in range(5):
btn_a = QtWidgets.QPushButton('btn_A_{}'.format(i))
btn_b = QtWidgets.QPushButton('btn_B_{}'.format(i))
for btn in [btn_a, btn_b]:
btn.setFixedSize(300, 30)
scroll_widget_a.vbox.addWidget(btn_a)
scroll_widget_b.vbox.addWidget(btn_b)
class ScrollWidget(QtWidgets.QScrollArea):
"""
スクロールエリアを入れたウィジェット
"""
def __init__(self):
super(ScrollWidget, self).__init__()
self.setWidgetResizable(True)
#
# ウィジェット / レイアウトの設置
#
widget = QtWidgets.QWidget()
self.setWidget(widget)
self.vbox = QtWidgets.QVBoxLayout(widget)
def launch_from_standalone():
"""
スタンドアロン用のウィンドウ起動
"""
standalone_app = QtWidgets.QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(standalone_app.exec_())
if __name__ == '__main__':
launch_from_standalone()
スプリッターをスプリッターで分割できる
QSplitter は QSplitter で分割できます。
これにより手軽に複雑な分割が可能です。
サンプルコード
import sys
from PySide2 import QtWidgets, QtCore
from PySide2.QtCore import Qt
class MainWindow(QtWidgets.QMainWindow):
"""
QSplitter
"""
def __init__(self):
super(MainWindow, self).__init__()
# ウィンドウサイズの指定
self.resize(QtCore.QSize(600, 600))
wrapper = QtWidgets.QWidget()
self.setCentralWidget(wrapper)
#
# ルートエリアの作成と設置
#
root_area = QtWidgets.QVBoxLayout()
wrapper.setLayout(root_area)
#
# スクロールウィジェットの作成
#
scroll_widget_a = ScrollWidget('A')
scroll_widget_b = ScrollWidget('B')
scroll_widget_c = ScrollWidget('C')
scroll_widget_d = ScrollWidget('D')
scroll_widget_e = ScrollWidget('E')
scroll_widget_f = ScrollWidget('F')
#
# スプリッターの作成
#
root_splitter = QtWidgets.QSplitter(Qt.Vertical)
child_splitter_a = QtWidgets.QSplitter(Qt.Horizontal)
child_splitter_c = QtWidgets.QSplitter(Qt.Horizontal)
#
# ルートの分割 | スプリッターにスプリッターが入れられる
#
root_splitter.addWidget(child_splitter_a)
root_splitter.addWidget(scroll_widget_c)
root_splitter.addWidget(child_splitter_c)
#
# 子のスプリッターに ScrollWidget を設置
#
child_splitter_a.addWidget(scroll_widget_a)
child_splitter_a.addWidget(scroll_widget_b)
child_splitter_c.addWidget(scroll_widget_d)
child_splitter_c.addWidget(scroll_widget_e)
child_splitter_c.addWidget(scroll_widget_f)
root_area.addWidget(root_splitter)
class ScrollWidget(QtWidgets.QScrollArea):
"""
スクロールエリアを入れたウィジェット
"""
def __init__(self, btn_label):
super(ScrollWidget, self).__init__()
self.setWidgetResizable(True)
#
# ウィジェット / レイアウトの設置
#
widget = QtWidgets.QWidget()
self.setWidget(widget)
vbox = QtWidgets.QVBoxLayout(widget)
#
# ボタンの作成と設置
#
for i in range(5):
btn = QtWidgets.QPushButton('btn_{}_{}'.format(btn_label, i))
btn.setFixedSize(300, 30)
vbox.addWidget(btn)
def launch_from_standalone():
"""
スタンドアロン用のウィンドウ起動
"""
standalone_app = QtWidgets.QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(standalone_app.exec_())
if __name__ == '__main__':
launch_from_standalone()
たまに使うメソッド
今のところスプリッターのメソッドを使う機会はほぼないんですが、
それでも何回か使ったことがあるメソッドだけ置いておきます。
スプリッターの位置を指定する
self.splitter.moveSplitter(<左端からの距離>, <インデックス>)
でスプリッターの位置を指定することができます。
Gif のコードは下記の文で実行しています。
self.splitter.moveSplitter(300, 2)
これを利用することでウィンドウが立ち上がった時の
スプリッターの位置を指定できます。
コード全文
import sys
from PySide2 import QtWidgets, QtCore
from PySide2.QtCore import Qt
class MainWindow(QtWidgets.QMainWindow):
"""
QSplitter
"""
def __init__(self):
super(MainWindow, self).__init__()
# ウィンドウサイズの指定
self.resize(QtCore.QSize(600, 300))
wrapper = QtWidgets.QWidget()
self.setCentralWidget(wrapper)
#
# ルートエリアの作成と設置
#
root_area = QtWidgets.QVBoxLayout()
wrapper.setLayout(root_area)
#
# スプリッターの作成
#
self.splitter = QtWidgets.QSplitter(Qt.Horizontal)
root_area.addWidget(self.splitter)
#
# ウィジェットの作成
#
plane_text_1 = QtWidgets.QPlainTextEdit()
plane_text_2 = QtWidgets.QPlainTextEdit()
plane_text_3 = QtWidgets.QPlainTextEdit()
#
# スプリッターへウィジェットを設置
#
self.splitter.addWidget(plane_text_1)
self.splitter.addWidget(plane_text_2)
self.splitter.addWidget(plane_text_3)
#
# ボタン
#
self.btn = QtWidgets.QPushButton('test')
self.btn.clicked.connect(self.btn_clicked)
root_area.addWidget(self.btn)
def btn_clicked(self):
self.splitter.moveSplitter(300, 2)
def launch_from_standalone():
"""
スタンドアロン用のウィンドウ起動
"""
standalone_app = QtWidgets.QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(standalone_app.exec_())
if __name__ == '__main__':
launch_from_standalone()
各ウィジェットのサイズを取得する
size = self.splitter.sizes()
上記のコードで size
に各ウィジェットのサイズがリスト型で入ります。
3つに分けている場合は3つ分のサイズが入ります。
コード全文
import sys
from PySide2 import QtWidgets, QtCore
from PySide2.QtCore import Qt
class MainWindow(QtWidgets.QMainWindow):
"""
QSplitter
"""
def __init__(self):
super(MainWindow, self).__init__()
# ウィンドウサイズの指定
self.resize(QtCore.QSize(600, 300))
wrapper = QtWidgets.QWidget()
self.setCentralWidget(wrapper)
#
# ルートエリアの作成と設置
#
root_area = QtWidgets.QVBoxLayout()
wrapper.setLayout(root_area)
#
# スプリッターの作成
#
self.splitter = QtWidgets.QSplitter(Qt.Horizontal)
root_area.addWidget(self.splitter)
#
# ウィジェットの作成
#
self.plane_text_1 = QtWidgets.QPlainTextEdit()
self.plane_text_2 = QtWidgets.QPlainTextEdit()
self.plane_text_3 = QtWidgets.QPlainTextEdit()
self.line_edit = QtWidgets.QLineEdit()
#
# スプリッターへウィジェットを設置
#
self.splitter.addWidget(self.plane_text_1)
self.splitter.addWidget(self.plane_text_2)
self.splitter.addWidget(self.plane_text_3)
root_area.addWidget(self.line_edit)
#
# ボタン
#
self.btn = QtWidgets.QPushButton('test')
self.btn.clicked.connect(self.btn_clicked)
root_area.addWidget(self.btn)
def btn_clicked(self):
size = self.splitter.sizes()
self.line_edit.clear()
self.line_edit.setText('サイズ:{}'.format(size))
def launch_from_standalone():
"""
スタンドアロン用のウィンドウ起動
"""
standalone_app = QtWidgets.QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(standalone_app.exec_())
if __name__ == '__main__':
launch_from_standalone()
QSS
見た目に関してはシンプルなウィジェットなので、QSS は特に書くものはないです。

class Splitter(QtWidgets.QSplitter):
def __init__(self, direction):
super(Splitter, self).__init__(direction)
self.handle_property = ''
self.handle_horizontal_property = ''
self.handle_horizontal_pressed_property = ''
self.handle_vertical_property = ''
self.handle_vertical_pressed_property = ''
self.init_widget()
def generate_property(self):
"""
プロパティの生成
"""
self.handle_property = '''
'''
self.handle_horizontal_property = '''
image: url(images/splitter_horizontal.png);
'''
self.handle_horizontal_pressed_property = '''
image: url(images/splitter_horizontal_pressed.png);
'''
self.handle_vertical_property = '''
image: url(images/splitter_vertical.png);
'''
self.handle_vertical_pressed_property = '''
image: url(images/splitter_vertical_pressed.png);
'''
def init_widget(self):
"""
ウィジェットの初期化
"""
#
# スプリッターの幅
#
self.setHandleWidth(25)
#
# プロパティ生成
#
self.generate_property()
#
# セレクタでプロパティを指定
#
self.setStyleSheet(
'QSplitter::handle{}'.format('{' + self.handle_property + '}') +
'QSplitter::handle:horizontal{}'.format('{' + self.handle_horizontal_property + '}') +
'QSplitter::handle:horizontal:pressed{}'.format('{' + self.handle_horizontal_pressed_property + '}') +
'QSplitter::handle:vertical{}'.format('{' + self.handle_vertical_property + '}') +
'QSplitter::handle:vertical:pressed{}'.format('{' + self.handle_vertical_pressed_property + '}')
)
コード全文
import sys
from PySide2 import QtWidgets, QtCore, QtGui
from PySide2.QtCore import Qt
# QSS 用変数
# ----------------------------------------------------------------------------------------------------------------------
# フォントに関する設定
FONT_FAMILY_JA = '游ゴシック'
MAIN_FONT_COLOR = '#cccccc'
MAIN_FONT_SIZE = 14
# 倍軽食
MAIN_BG_COLOR = '#3a3a3a'
BLUE_01 = '#0059A4'
TOUCH_COLOR = '#525252'
TOUCH_COLOR_02 = '#5c5c5c'
BORDER_COLOR = '#646464'
'''
------------------------------------------------------------------------------------------------------------------------
QSplitter
------------------------------------------------------------------------------------------------------------------------
'''
class Splitter(QtWidgets.QSplitter):
def __init__(self, direction):
super(Splitter, self).__init__(direction)
self.handle_property = ''
self.handle_horizontal_property = ''
self.handle_horizontal_pressed_property = ''
self.handle_vertical_property = ''
self.handle_vertical_pressed_property = ''
self.init_widget()
def generate_property(self):
"""
プロパティの生成
"""
self.handle_property = '''
'''
#
# 横分割
#
self.handle_horizontal_property = '''
image: url(images/splitter_horizontal.png);
'''
self.handle_horizontal_pressed_property = '''
image: url(images/splitter_horizontal_pressed.png);
'''
#
# 縦分割
#
self.handle_vertical_property = '''
image: url(images/splitter_vertical.png);
'''
self.handle_vertical_pressed_property = '''
image: url(images/splitter_vertical_pressed.png);
'''
def init_widget(self):
"""
ウィジェットの初期化
"""
#
# スプリッターの幅
#
self.setHandleWidth(25)
#
# プロパティ生成
#
self.generate_property()
#
# セレクタでプロパティを指定
#
self.setStyleSheet(
'QSplitter::handle{}'.format('{' + self.handle_property + '}') +
'QSplitter::handle:horizontal{}'.format('{' + self.handle_horizontal_property + '}') +
'QSplitter::handle:horizontal:pressed{}'.format('{' + self.handle_horizontal_pressed_property + '}') +
'QSplitter::handle:vertical{}'.format('{' + self.handle_vertical_property + '}') +
'QSplitter::handle:vertical:pressed{}'.format('{' + self.handle_vertical_pressed_property + '}')
)
'''
------------------------------------------------------------------------------------------------------------------------
ウィンドウ
------------------------------------------------------------------------------------------------------------------------
'''
class MainWindow(QtWidgets.QMainWindow):
"""
ウィンドウ
"""
def __init__(self):
super(MainWindow, self).__init__()
# ウィンドウサイズの指定
self.resize(QtCore.QSize(600, 600))
self.setStyleSheet(
'background-color:{}'.format(MAIN_BG_COLOR)
)
wrapper = QtWidgets.QWidget()
self.setCentralWidget(wrapper)
#
# ルートエリアの作成と設置
#
root_area = QtWidgets.QVBoxLayout()
wrapper.setLayout(root_area)
#
# スクロールウィジェットの作成
#
scroll_widget_a = ScrollWidget('A')
scroll_widget_b = ScrollWidget('B')
scroll_widget_c = ScrollWidget('C')
scroll_widget_d = ScrollWidget('D')
scroll_widget_e = ScrollWidget('E')
scroll_widget_f = ScrollWidget('F')
#
# スプリッターの作成
#
root_splitter = Splitter(Qt.Vertical)
child_splitter_a = Splitter(Qt.Horizontal)
child_splitter_c = Splitter(Qt.Horizontal)
#
# ルートの分割 | スプリッターにスプリッターが入れられる
#
root_splitter.addWidget(child_splitter_a)
root_splitter.addWidget(scroll_widget_c)
root_splitter.addWidget(child_splitter_c)
#
# 子のスプリッターに ScrollWidget を設置
#
child_splitter_a.addWidget(scroll_widget_a)
child_splitter_a.addWidget(scroll_widget_b)
child_splitter_c.addWidget(scroll_widget_d)
child_splitter_c.addWidget(scroll_widget_e)
child_splitter_c.addWidget(scroll_widget_f)
root_area.addWidget(root_splitter)
'''
------------------------------------------------------------------------------------------------------------------------
QScrollArea の QSS
------------------------------------------------------------------------------------------------------------------------
'''
class ScrollArea(QtWidgets.QScrollArea):
"""
QScrollArea に QSS 設定したやつ
"""
def __init__(self,
font_family=FONT_FAMILY_JA, font_color=MAIN_FONT_COLOR, bg_color=MAIN_BG_COLOR,
touch_color=TOUCH_COLOR_02, highlight_color=BLUE_01, border_color=BORDER_COLOR
):
super(ScrollArea, self).__init__()
self.setWidgetResizable(True)
self.font_family = font_family
self.font_color = font_color
self.highlight_color = highlight_color
self.touch_color = touch_color
self.bg_color = bg_color
self.border_color = border_color
self.scroll_bar = ''
self.scroll_bar_handle = ''
self.scroll_bar_handle_horizontal = ''
self.scroll_bar_handle_vertical = ''
self.scroll_bar_page = ''
self.scroll_bar_horizontal = ''
self.scroll_bar_sub_line_horizontal = ''
self.scroll_bar_add_line_horizontal = ''
self.scroll_bar_vertical = ''
self.scroll_bar_sub_line_vertical = ''
self.scroll_bar_add_line_vertical = ''
self.init_widget()
#
# プロパティの生成
#
# ------------------------------------------------------------------------------------------------------------------
def generate_property(self):
"""
各プロパティの設定
"""
# スクロールバー全体
self.scroll_bar = '''
background-color:transparent;
border:0px solid red;
'''
# ハンドル
self.scroll_bar_handle = '''
background-color:{};
border: 1px solid #2c2c2c;
'''.format(
self.touch_color
)
# 横のハンドル
self.scroll_bar_handle_horizontal = '''
background-image: url(images/icon_handle_horizontal.png);
background-repeat: no-repeat;
background-position: center;
min-width: 50px;
'''
self.scroll_bar_handle_vertical = '''
background-image: url(images/icon_handle_vertical.png);
background-repeat: no-repeat;
background-position: center;
min-height: 50px;
'''
# ハンドルの外
self.scroll_bar_page = '''
background-color:#2c2c2c;
border: 0px solid #8e8e8e;
'''
margin = 0
border_width = 0
scroller_width = 18
#
#
#
# 横のスクロールバー全体 | 主に幅の設定
#
self.scroll_bar_horizontal = '''
margin: 0px {}px;
height:{}px;
padding-top:{}px;
border-top: 0px solid {};
'''.format(
scroller_width,
scroller_width,
margin,
border_width,
self.border_color,
)
#
# 左のボタン
#
self.scroll_bar_sub_line_horizontal = '''
subcontrol-position:left;
subcontrol-origin:margin;
width:{}px;
background-color:{};
border: 1px solid #2c2c2c;
image: url(images/icon_left.png);
'''.format(
scroller_width,
self.touch_color,
)
# 右のボタン
self.scroll_bar_add_line_horizontal = '''
subcontrol-position:right;
subcontrol-origin:margin;
width:{}px;
background-color:{};
border:1px solid #2c2c2c;
image: url(images/icon_right.png);
'''.format(
scroller_width,
self.touch_color,
)
#
# 縦のスクロールバー
#
# 縦のスクロールバー
self.scroll_bar_vertical = '''
margin: {}px 0px;
width:{}px;
'''.format(
scroller_width,
scroller_width,
)
# 上のボタン
self.scroll_bar_sub_line_vertical = '''
subcontrol-position:top;
subcontrol-origin:margin;
height:{}px;
background-color:{};
border: 1px solid #2c2c2c;
image: url(images/icon_top.png);
'''.format(
scroller_width,
self.touch_color,
)
# 下のボタン
self.scroll_bar_add_line_vertical = '''
subcontrol-position:bottom;
subcontrol-origin:margin;
height:{}px;
background-color:{};
border:1px solid #2c2c2c;
image: url(images/icon_bottom.png);
'''.format(
scroller_width,
self.touch_color,
)
#
# QSS の設定
#
# ------------------------------------------------------------------------------------------------------------------
def init_widget(self):
"""
ウィジェットの初期化
"""
# プロパティ を生成
self.generate_property()
self.setStyleSheet(
'QScrollArea{border:0px solid #000;}' +
'QScrollBar{}'.format('{' + self.scroll_bar + '}') +
'QScrollBar::handle{}'.format('{' + self.scroll_bar_handle + '}') +
'QScrollBar::handle:horizontal{}'.format('{' + self.scroll_bar_handle_horizontal + '}') +
'QScrollBar::handle:vertical{}'.format('{' + self.scroll_bar_handle_vertical + '}') +
'QScrollBar::sub-page{}'.format('{' + self.scroll_bar_page + '}') +
'QScrollBar::add-page{}'.format('{' + self.scroll_bar_page + '}') +
'QScrollBar:horizontal{}'.format('{' + self.scroll_bar_horizontal + '}') +
'QScrollBar::sub-line:horizontal{}'.format('{' + self.scroll_bar_sub_line_horizontal + '}') +
'QScrollBar::add-line:horizontal{}'.format('{' + self.scroll_bar_add_line_horizontal + '}') +
'QScrollBar:vertical{}'.format('{' + self.scroll_bar_vertical + '}') +
'QScrollBar::sub-line:vertical{}'.format('{' + self.scroll_bar_sub_line_vertical + '}') +
'QScrollBar::add-line:vertical{}'.format('{' + self.scroll_bar_add_line_vertical + '}')
)
'''
------------------------------------------------------------------------------------------------------------------------
QPushButton の QSS
------------------------------------------------------------------------------------------------------------------------
'''
class PushButton(QtWidgets.QPushButton):
"""
QPushButton の QSS つけたやつ
"""
def __init__(
self,
label_text=None, put_area=None,
font_color=MAIN_FONT_COLOR, font_family=FONT_FAMILY_JA, bg_color=TOUCH_COLOR, hover_bg_color=BLUE_01,
*args, **kwargs
):
super(PushButton, self).__init__(label_text, *args, **kwargs)
self.put_area = put_area
self.font_family = font_family
self.font_color = font_color
self.bg_color = bg_color
self.hover_bg_color = hover_bg_color
self.push_button_qss = ''
self.push_button_hover_qss = ''
self.init_ui()
def generate_property(self):
"""
プロパティの生成
"""
height = 28
self.push_button_qss = '''
color:{};
height: {}px;
font-size: 12px;
font-weight: bold;
background-color:{};
border: 2px solid #7d7d7d;
border-radius: {}px;
'''.format(
self.font_color,
height,
self.bg_color,
height / 2
)
self.push_button_hover_qss = '''
color:#fff;
background-color:{};
'''.format(
self.hover_bg_color
)
def init_ui(self):
if self.put_area is not None:
self.put_area.addWidget(self)
self.generate_property()
# フォントの設定
self.setFont(QtGui.QFont(self.font_family))
self.setStyleSheet(
'QPushButton{}'.format('{' + self.push_button_qss + '}') +
'QPushButton:hover{}'.format('{' + self.push_button_hover_qss + '}')
)
'''
------------------------------------------------------------------------------------------------------------------------
スクロールウィジェット
------------------------------------------------------------------------------------------------------------------------
'''
class ScrollWidget(ScrollArea):
"""
スクロールエリアを入れたウィジェット
"""
def __init__(self, btn_label):
super(ScrollWidget, self).__init__()
self.setWidgetResizable(True)
#
# ウィジェット / レイアウトの設置
#
widget = QtWidgets.QWidget()
widget.setStyleSheet(
'border:0px solid #000;'
)
self.setWidget(widget)
vbox = QtWidgets.QVBoxLayout(widget)
#
# ボタンの作成と設置
#
for i in range(5):
btn = PushButton('btn_{}_{}'.format(btn_label, i))
btn.setFixedSize(300, 30)
vbox.addWidget(btn)
def launch_from_standalone():
"""
スタンドアロン用のウィンドウ起動
"""
standalone_app = QtWidgets.QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(standalone_app.exec_())
if __name__ == '__main__':
launch_from_standalone()
幅を変更する
プロパティの width
でもできるそうなんですが(PyQt や PySide6 だけかもしれない)、
私はメソッドでできるものはメソッドで指定する癖があります。
self.setHandleWidth(25)
上記は QSplitter の幅を 25px にします。
セレクタとプロパティ
セレクタとプロパティは特に気にするものはないように思います。
hover が効かないくらいでしょうか。
画像が指定できればそれで充分な気がします。
self.setStyleSheet(
'''
QSplitter::handle{
background-color: #aa0098;
}
QSplitter::handle:horizontal{
image: url(images/hoge.png);
}
QSplitter::handle:horizontal:pressed{
image: url(images/hoge.png);
}
QSplitter::handle:vertical{
image: url(images/hoge.png);
}
QSplitter::handle:vertical:pressed{
image: url(images/hoge.png);
}
'''
)