PySide6 Customized Window

2022. 5. 21. 23:57IT

Pyside6를 License model 때문에 사용하기 시작했다. 

 

그런데 쉽지가 않은 부분들이 있다. 테스트 용도로 간단한 프로그램을 만들었는데 윈도우 리사이즈에서 막혔다. Menu bar가 window title에 나타나도록 하기 위해서 customizing을 하는데 생각보다 쉽지 않다. 구글링을 Pyside6로 해도 별로 나오지가 않는다.

 

 

 

 

그래도 여기엔 css를 써서 style을 정하는 stylesheet도 들어가 있다. 일괄적용하는 부분과 별도 적용하는 부분이 모두 들어 있다. 구미에 맞는 것을 골라쓰면 된다. 

 

 

import sys
from PySide6.QtCore import QPoint, Qt, QRect
from PySide6.QtWidgets import QApplication, QMainWindow, QMessageBox, QLabel, QComboBox, QFileDialog, QScrollArea, \
    QWidget, QLineEdit, QProgressDialog
from PySide6.QtWidgets import (QMainWindow, QApplication, QPushButton, QHBoxLayout,
                             QVBoxLayout, QTabWidget, QWidget,
                             QLabel, QSizeGrip, QMenuBar, QToolBar)
from PySide6.QtGui import QIcon, QAction, QFont, QPixmap, QGuiApplication

from PySide6.QtGui import QIcon
from PySide6.QtCore import QThread, SIGNAL

css = """
QMenuBar {
    background-color: qlineargradient(x1:0, y1:0, x2:0, y2:1,
                                      stop:0 lightgray, stop:1 darkgray);
}
QMenuBar::item {
    spacing: 3px;           
    padding: 2px 10px;
    background-color: rgb(210,105,30);
    color: rgb(255,255,255);  
    border-radius: 5px;
}
QMenuBar::item:selected {    
    background-color: rgb(244,164,96);
}
QMenuBar::item:pressed {
    background: rgb(128,0,0);
}

/* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */  
QToolBar {
    background-color: white;
    color: rgb(255,255,255); 
}

/* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */  

QMenu {
    background-color: #ABABAB;   
    border: 1px solid black;
    margin: 2px;
}
QMenu::item {
    background-color: transparent;
}
QMenu::item:selected { 
    background-color: #654321;
    color: rgb(255,255,255);
}
"""

class ToolBar(QWidget):
    height = 48
    def __init__(self, parent):
        super(ToolBar, self).__init__()
        self.parent = parent
        self.layout = QHBoxLayout()
        self.layout.setContentsMargins(0,0,0,0)

        self.toolbar = QToolBar("My main toolbar")
        button_action = QAction(QIcon('./resources/tb_open.png'), "Your button", self)
        button_action.setStatusTip("This is your button")
        button_action.triggered.connect(self.onMyToolBarButtonClick)
        self.toolbar.addAction(button_action)
        self.toolbar.setStyleSheet("""
                                            background-color: white;
                                            background: white;                    
                                            selection-color: white;
                                            selection-background-color: white;
                                            font-family: "Arial";
                                            padding-left: 4px;
                                        """)

        self.layout.addWidget(self.toolbar)
        self.setLayout(self.layout)

    def onMyToolBarButtonClick(self):
        print("toolbar clicked")


class TitleBar(QWidget):
    height = 32
    def __init__(self, parent):
        super(TitleBar, self).__init__()
        self.parent = parent
        self.layout = QHBoxLayout()
        self.layout.setContentsMargins(0,0,0,0)

        self.imageLabel = QLabel(self)
        self.imageLabel.setPixmap(QPixmap("./resources/bluewave24.png"))  # 컴파일 폴더에 있는 경우
        self.imageLabel.setStyleSheet("""
                                    background-color: #808080;
                                    background: #808080;                    
                                    selection-color: white;
                                    selection-background-color: #4169E1;
                                    font-family: "Arial";
                                    padding-left: 4px;
                                """)
        self.layout.addWidget(self.imageLabel)


        self.menu_bar = QMenuBar()
        self.menu_bar.setStyleSheet("""
                            font-size: 14px;
                            color: white;
                            background-color: #808080;
                            background: #808080;                    
                            selection-color: white;
                            selection-background-color: #4169E1;
                            font-family: "Arial";
                            padding-top: 4px;
                            padding-left: 10px;
                        """)

        self.menu_file = self.menu_bar.addMenu('file')

        openAction = QAction(QIcon('./resources/open.png'), 'Open', self)
        openAction.setShortcut('Ctrl+O')
        openAction.triggered.connect(self.menu_open)
        self.menu_file_open = self.menu_file.addAction(openAction)


        self.menu_file_save=self.menu_file.addAction('save')
        self.menu_file_saveas=self.menu_file.addAction('save as...')
        self.menu_file_quit=self.menu_file.addAction('exit')
        self.menu_file_quit.triggered.connect(QApplication.quit)

        self.menu_work=self.menu_bar.addMenu('work')
        self.menu_analysis=self.menu_bar.addMenu('analysis')
        self.menu_edit=self.menu_bar.addMenu('edit')
        self.menu_window=self.menu_bar.addMenu('window')
        self.menu_help=self.menu_bar.addMenu('help')

        self.layout.addWidget(self.menu_bar)


        self.title = QLabel(" [Bluewave v1.0]")
        self.title.setFixedHeight(self.height)
        self.layout.addWidget(self.title)
        self.title.setStyleSheet("""
            icon: desktop-icon;
            background-color: #808080;  /* 23272a   #f00*/
            font-size: 13px;
            font-family: "Arial";
            color: white;
            padding-left: 0px;
            padding-top: px;
        """)

        self.closeButton = QPushButton(' ')
        self.closeButton.clicked.connect(self.on_click_close)
        self.closeButton.setStyleSheet("""
            background-color: #DC143C;
            border-radius: 10px;
            height: {};
            width: {};
            margin-right: 3px;
            font-weight: bold;
            color: #000;
            font-family: "Webdings";
            qproperty-text: "r";
        """.format(self.height/1.7,self.height/1.7))

        self.maxButton = QPushButton(' ')
        self.maxButton.clicked.connect(self.on_click_maximize)
        self.maxButton.setStyleSheet("""
            background-color: #32CD32;
            border-radius: 10px;
            height: {};
            width: {};
            margin-right: 3px;
            font-weight: bold;
            color: #000;
            font-family: "Webdings";
            qproperty-text: "1";
        """.format(self.height/1.7,self.height/1.7))

        self.hideButton = QPushButton(' ')
        self.hideButton.clicked.connect(self.on_click_hide)
        self.hideButton.setStyleSheet("""
            background-color: #FFFF00;
            border-radius: 10px;
            height: {};
            width: {};
            margin-right: 3px;
            font-weight: bold;
            color: #000;
            font-family: "Webdings";
            qproperty-text: "0";
        """.format(self.height/1.7,self.height/1.7))

        self.layout.addWidget(self.hideButton)
        self.layout.addWidget(self.maxButton)
        self.layout.addWidget(self.closeButton)
        self.setLayout(self.layout)

        self.start = QPoint(0, 0)
        self.pressing = False
        self.maximaze = False

    def menu_open(self):
        print("Menu open clicked")

    def resizeEvent(self, QResizeEvent):
        super(TitleBar, self).resizeEvent(QResizeEvent)
        self.title.setFixedWidth(self.parent.width())

    def mousePressEvent(self, event):
        self.start = self.mapToGlobal(event.pos())
        self.pressing = True

    def mouseMoveEvent(self, event):
        if self.pressing:
            self.end = self.mapToGlobal(event.pos())
            self.movement = self.end-self.start
            self.parent.move(self.mapToGlobal(self.movement))
            self.start = self.end

    def mouseReleaseEvent(self, QMouseEvent):
        self.pressing = False

    def on_click_close(self):
        sys.exit()

    def on_click_maximize(self):
        self.maximaze = not self.maximaze
        if self.maximaze:    self.parent.setWindowState(Qt.WindowNoState)
        if not self.maximaze:
            self.parent.setWindowState(Qt.WindowMaximized)

    def on_click_hide(self):
        self.parent.showMinimized()


class StatusBar(QWidget):
    def __init__(self, parent):
        super(StatusBar, self).__init__()
        self.initUI()
        self.showMessage("showMessage: Hello world!")

    def initUI(self):
        self.label = QLabel("Status bar...")
        self.label.setFixedHeight(24)
        self.label.setAlignment(Qt.AlignLeft | Qt.AlignVCenter)
        self.label.setStyleSheet("""
            background-color: #808080;
            font-size: 14px;
            padding-left: 30px;
            color: white;
        """)
        self.layout = QHBoxLayout()
        self.layout.setContentsMargins(0,0,0,0)
        self.layout.addWidget(self.label)
        self.setLayout(self.layout)

    def showMessage(self, text):
        self.label.setText(text)


class MainWindow(QWidget):
    def __init__(self):
        super(MainWindow, self).__init__()
        self.setFixedSize(800, 400)
        #self.setGeometry(100, 100, 800, 768)
        self.setWindowFlags(self.windowFlags() | Qt.FramelessWindowHint)
        self.setStyleSheet("background-color: #808080;")

        self.title_bar = TitleBar(self)
        self.tool_bar = ToolBar(self)
        self.status_bar = StatusBar(self)

        self.layout  = QVBoxLayout()
        self.layout.setContentsMargins(0,0,0,0)
        self.layout.addWidget(self.title_bar)
        self.layout.setSpacing(0)
        self.layout.addWidget(self.tool_bar)
        self.layout.addStretch(1)
        self.layout.addWidget(self.status_bar)
        self.layout.setSpacing(1)
        self.setLayout(self.layout)


if __name__ == "__main__":
    app = QApplication(sys.argv)
    app.setStyleSheet(css)
    mw = MainWindow()
    mw.show()
    app.exec()
반응형