1. 파이썬에서 Qt Resource 에 리소스 추가하기

2. 파이썬 코드에서 Resource 파일에서 데이터 사용하기

에 대해 알아보도록 하겠습니다.

 

1. 파이썬에서 Qt Resource 에 리소스 추가하기

1) 리소스 파일 생성

resource.qrc라는 파일명으로 아래와 같이 리소스 파일을 만들어 줍니다.

- <file></file> 태그 안에 추가할 리소스 경로를 넣어 추가해 줍니다.

- file 태그 안의 경로는 resource.qrc 파일이 있는 위치부터의 경로를 넣고, 해당 경로에 실제 파일이 존재해야 합니다.

<RCC>
    <qresource prefix="/">
        <file>img/icon.jpg</file>
        <file>data/text.txt</file>        
    </qresource>
</RCC>

2) 리소스 파일 변환

터미널에서 아래 명령을 실행하여 resource.qrc 파일을 .py 파일로 변환합니다. (pyrcc5.exe가 설치되어 있어야 함)

pyrcc5 resource.qrc -o resource_qrc.py

3) 리소스 파일 import

리소스를 사용하고자 하는 python 파일에서 아래와 같이 리소스를 import 합니다.

from . import resource_qrc

여기까지 하면 파이썬 코드에서 리소스를 사용하기 위한 준비가 끝났습니다.

아래에서는 리소스에서 파일을 읽어 사용하는 법을 알아보도록 하겠습니다.

 

2. 파이썬 코드에서 Resource 의 데이터 사용하기

읽을 파일의 경로명 앞에 ":" 을 추가하고 prefix를 포함한 경로명을 적어주면 됩니다.

1) 그림 파일의 경우

위의 예에서 본 리소스 파일에서, img/icon.jpg 을 읽어오는 방법입니다.

pixmap = QPixmap(":/img/icon.jpg")

아이콘으로 읽고 싶다면 아래와 같이 합니다.

icon = QIcon(":/img/icon.jpg")

2) 텍스트 파일의 경우

- 일반적으로 python에서는 with open 또는 open 함수를 이용해 파일을 열지만, 리소스 파일 안에 있는 텍스트나 바이너리 파일을 읽는 경우 QFile 클래스를 사용해야 합니다.

 

- 파이썬에서 open 후 readlines() 하면 자동으로 라인별로 split된 결과가 리턴되지만, QTextStream.readAll()을 하면 통으로 된 데이터가 리턴됩니다. 따라서, 아래와 같이 '\n'으로 split한 결과를 리턴하는 함수를 만들면 readlines와 유사한 결과를 얻을 수 있습니다.

lines = readTextFileFromResource(":/data/text.txt")

def readDataFromResource(path, codec = 'UTF-8'):
    fd = QFile(path)
    data = None
    if fd.open(QIODevice.ReadOnly | QFile.Text):
        ts = QTextStream(fd)
        ts.setCodec(codec)
        data = ts.readAll()
        fd.close()
    return data.split('\n')
/*  QcomboBox style */
QComboBox {
    border: 1px solid gray;   /*  Border */
    border-radius: 3px;   /*  Round */
    padding: 1px 18px 1px 3px;   /*  Font fill */
    color: #000;
    font: normal normal 15px "Microsoft YaHei";
    background: transparent;
}

/*  After dropping, the entire drop-down form style */
QComboBox QAbstractItemView {
    outline: 0px solid gray;   /*  The virtual frame of the selected item */
    border: 1px solid yellow;   /*  Border of the entire drop-down form */
    color: green;
    background-color: red;   /*  Whole drop-down form background color */
    selection-background-color: lightgreen;   /*  The whole drop-down window is selected from the background color of the item */
}

/*  Down pull, the entire drop-down window */
QComboBox QAbstractItemView::item {
    height: 50px;   /*  The height of the item (set pcomboBox-> setView (new qlistview ()); after this item works) */
}

/*  After dropping, the entire drop-down window crossing each pattern */
QComboBox QAbstractItemView::item:hover {
    color: #FFFFFF;
    background-color: lightgreen;   /*  The whole drop-down window crosss the background color of each item */
}

/*  After dropping, the entire drop-down window is selected for each pattern. */
QComboBox QAbstractItemView::item:selected {
    color: #FFFFFF;
    background-color: lightgreen;
}

/*  Vertical scroll bar in qcomboBox */
QComboBox QAbstractScrollArea QScrollBar:vertical {
    width: 10px;
    background-color: #d0d2d4;   /*  Blank area Gray Green */
}

QComboBox QAbstractScrollArea QScrollBar::handle:vertical {
    border-radius: 5px;   /*  Round */
    background: rgb(160,160,160);   /*  Small square background color dark gray lightblue */
}

QComboBox QAbstractScrollArea QScrollBar::handle:vertical:hover {
    background: rgb(90, 91, 93);   /*  Crossing the small square background color Yellow */
}

/*  Set to edit (TRUE) Editable, the style of editing area */
QComboBox:editable {
    background: green;
}

/*  Set to non-editing (STEDITABLE)! EDITABLE, the whole qComboBox style */
QComboBox:!editable {
     background: blue;
}

/*  When set to edit Editable, click on the style of the entire QComboBox */
QComboBox:editable:on {
    background: green;
}

/*  When set to non-editing! Editable, click on the whole qComboBox style. */
QComboBox:!editable:on {
     background: blue;
}

/*  Set to edit Editable, the drop-down box style */
QComboBox::drop-down:editable {
    background: lightblue;
}

/*  When set to edit Editable, click the dropped box style. */
QComboBox::drop-down:editable:on {
    background: lightgreen;
}

/*  Set to non-editing! Editable, drop-down box style */
QComboBox::drop-down:!editable {
    background: lightblue;
}

/*  When set to non-editing! Editable, click the dropped box style. */
QComboBox::drop-down:!editable:on {
    background: lightgreen;
}

/*  Click qComboBox */
QComboBox:on {
}

/*  Pull-up box pattern */
QComboBox::drop-down {
    subcontrol-origin: padding;   /*  The origin rectangle of the child control in the parent element. If this property is not specified, the default is padding. */
    subcontrol-position: top right;   /*  Down-pull box position (upper right) */
    width: 15px;   /*  Down-pull box width */

    border-left-width: 1px;   /*  Down-pull frame on the left boundary width */
    border-left-color: darkgray;   /*  Down-pull frame on the left line color */
    border-left-style: solid;   /*  The left side of the drop-down frame is a solid line */
    border-top-right-radius: 3px;   /*  Rounded radius of the upper right border line of the drop box (should be consistent with the rounded radius of the entire QCOMBOBOX right on the right side) */
    border-bottom-right-radius: 3px;   /*  Equally */
}/ * Crossing the pull frame pattern * /  

QComboBox::drop-down:hover {    background: yellow;  }

/* Drop the arrow style */ 
QComboBox::down-arrow { 
width: 15px; /*  The width of the drop-down arrow (recommended with the width of the drop-down Drop-Down) */ 
background: transparent; /*  Drop the arrow background color */ 
padding: 0px 0px 0px 0px; /*  Upper margins, right inner margins, lower margins, left within and left */ 
image: url(:/images/combobox_arrow_down.png); } 

/*  Click to pull the arrow */ 
QComboBox::down-arrow:on { image: url(:/images/combobox_arrow_up.png); /*  Show drop-down arrow */ }

QComboBox::indicator{
    background-color:transparent;
    selection-background-color:transparent;
    color:transparent;
    selection-color:transparent;
}

note: QComboBox* pComboBox = new QComboBox(this); 
pComboBox->setView(new QListView());   //The drop-down column key can take effect

 

트리뷰에 콤보박스를 추가해서 옵션을 선택하도록 하는 방법입니다.

  • 일부 아이템에만 우측에 콤보박스 추가
  • 버튼을 누르면 현재 선택된 아이템의 정보를 보여줌

결과 화면 : 

 

설명 : 

  • 파일에서 데이터를 읽어와 treeView에 아이템을 추가합니다.(한 row에 아이템 2개씩 추가)
    • 콤보박스가 없는 row : [정보가 있는 item, 빈 item] 두개 추가
    • 콤보박스가 있는 row : [정보가 있는 item, 콤보박스의 초기값을 가지는 item] 두개 추가
    • 콤보 박스를 추가 하고 싶은 아이템을 구분하기 위해, 데이터 파일에서 #count가 있으면 콤보 박스를 생성하게 했습니다.(콤보박스 초기값이 count)
  • ComboBox를 보여줄 수 있는 Delegate를 만듭니다.
  • column 1에 위의 combo box용 delegate를 설정해 줍니다.
    self.treeView.setItemDelegateForColumn(1, ComboDelegate(self, ["count", "1", "2", "3"]))​

전체 소스 코드 :

TreeView.py

from PyQt5.QtWidgets import QDialog, QTreeView, QStyledItemDelegate, QComboBox, QWidget, QApplication, \
    QStyleOptionComboBox, QVBoxLayout, QPushButton, QLabel, QItemDelegate, QStyle
from PyQt5.QtGui import QStandardItem, QStandardItemModel
from PyQt5.QtCore import Qt, QVariant

class TreeViewDialog(QDialog):
    def __init__(self):
        QDialog.__init__(self)
        self.treeView = QTreeView(self)
        self.model = TreeModel()
        self.treeView.setModel(self.model)
        self.treeView.setHeaderHidden(True)
        self.treeView.setItemDelegateForColumn(1, ComboDelegate(self, ["count", "1", "2", "3"]))
        self.treeView.setCurrentIndex(self.model.index(0, 0))
        self.treeView.setColumnWidth(0, 300)
        self.treeView.expandAll()
        self.treeView.clicked.connect(self.treeViewClicked)

        self.button = QPushButton(self)
        self.button.setText("Show selected item")
        self.button.clicked.connect(self.onButtonClicked)
        self.label = QLabel(self)
        self.label.setText("...")

        vBox = QVBoxLayout(self)
        vBox.addWidget(self.treeView)
        vBox.addWidget(self.button)
        vBox.addWidget(self.label)
        self.setLayout(vBox)
        self.resize(500, 300)

    def onButtonClicked(self):
        indexes = self.treeView.selectedIndexes()
        txt = ''
        for index in indexes:
            txt += '{},'.format(index.data())
        self.label.setText(txt)

    def treeViewClicked(self, index):
        if not index.isValid():
            return
        print('row {}, col {}'.format(index.row(), index.column()))


class TreeModel(QStandardItemModel):
    def __init__(self):
        super(TreeModel, self).__init__()
        self.readData()

    def readData(self):
        rootParentItem = self.invisibleRootItem()
        roots = set()
        item = None
        with open('data.txt', 'r', encoding='utf-8') as f:
            lines = f.readlines()
        for line in lines:
            line = line.strip()
            subs = line.split(">")
            category = subs[0]
            if category not in roots:
                item = self.appendChild(category, rootParentItem, category)
                roots.add(category)
            if len(subs) > 1:
                name = subs[1]
                self.appendChild(name, item, name)

    def appendChild(self, title, parentItem, toolTip = None):
        item2 = None
        if '#count' in title:
            item2 = TreeItem('count', "")
            title = title.replace("#count", "")
        else:
            item2 = TreeItem('', '')
            item2.setEditable(False)
        item = TreeItem(title, toolTip)
        item.setData(title)
        item.setEditable(False)
        parentItem.appendRow([item, item2])
        return item


class TreeItem(QStandardItem):
    def __init__(self, text, toolTip):
        QStandardItem.__init__(self)
        self.setText(text)
        self.setToolTip(toolTip)


class ComboDelegate(QStyledItemDelegate):
    def __init__(self, owner, items):
        super(ComboDelegate, self).__init__(owner)
        self.items = items

    def createEditor(self, parent, option, index):
        self.editor = QComboBox(parent)
        self.editor.addItems(self.items)
        return self.editor

    def paint(self, painter, option, index):
        if index.data(Qt.DisplayRole) == '':	# 빈 아이템이면 콤보박스 안보임
            QStyledItemDelegate.paint(self, painter, option, index)
        else:	# 값이 있는 아이템이면 콤보박스 보임
            value = index.data(Qt.DisplayRole)
            style = QApplication.style()
            opt = QStyleOptionComboBox()
            opt.text = str(value)
            opt.rect = option.rect
            style.drawComplexControl(QStyle.CC_ComboBox, opt, painter)
            QStyledItemDelegate.paint(self, painter, option, index)

    def setEditorData(self, editor, index):
        value = index.data(Qt.DisplayRole)
        num = self.items.index(value)
        editor.setCurrentIndex(num)
        if index.column() == 1: 
            editor.showPopup()

    def setModelData(self, editor, model, index):
        value = editor.currentText()
        model.setData(index, QVariant(value),  Qt.DisplayRole)

    def updateEditorGeometry(self, editor, option, index):
        editor.setGeometry(option.rect)

if __name__ == '__main__':
    import sys
    app = QApplication(sys.argv)
    treeview = TreeViewDialog()
    treeview.show()
    sys.exit(app.exec_())

 

data.txt

Fruits>Apple#count
Fruits>Banana#count
Fruits>Grape
Vegetables>Tomato#count
Vegetables>Cucumber#count​

QTreeView의 아이템에 마우스를 올리면, 각 아이템 별로 다른 말풍선(툴팁)이 보여지도록 합니다.

결과 화면 :

 

소스 코드 :

  1. 다이얼로그에 QTreeView를 생성합니다.
  2. 모델을 생성해서, treeView에 연결합니다. (아래에서는 QStandardItemModel을 사용)
  3. 모델에 아이템을 추가할 때, QStandardItem을 상속받은 TreeItem 클래스를 정의해서 사용합니다.
    • TreeItem 생성 시, 인자로 아이템에 입력할 데이터와, 툴팁 정보를 받음
    • item에 입력받은 데이터와 툴팁을 설정함
# qt/treeview/TreeView.py

from PyQt5.QtWidgets import QDialog, QTreeView
from PyQt5.QtGui import QStandardItem, QStandardItemModel

class TreeViewDialog(QDialog):
    def __init__(self):
        QDialog.__init__(self)
        self.treeView = QTreeView(self)
        self.model = QStandardItemModel()
        self.treeView.setModel(self.model)
        self.treeView.setHeaderHidden(True)
        rootParentItem = self.model.invisibleRootItem()
        # Add first item and it's children
        item = self.appendChild("category 1", rootParentItem, 'tooltip 1')
        for i in range(3):
            self.appendChild('a {}'.format(i), item, 'a tooltip {}'.format(i))

        # Add second item and it's children
        item = self.appendChild("category 2", rootParentItem, 'tooltip 1')
        for i in range(3):
            self.appendChild('b {}'.format(i), item, 'b tooltip {}'.format(i))

        self.treeView.setCurrentIndex(self.model.index(0, 0))
        self.treeView.expandAll()
        self.resize(400,200)

    def appendChild(self, title, parentItem, toolTip = None):
        item = TreeItem(title, toolTip)
        item.setData(title)
        parentItem.appendRow(item)
        return item


class TreeItem(QStandardItem):
    def __init__(self, text, toolTip):
        QStandardItem.__init__(self)
        self.setText(text)
        self.setToolTip(toolTip)

 

  4. 위 다이얼로그 실행을 위한 메인 파일

# main.py
from qt.treeview.TreeView import *
import sys

def start():
    app = QApplication(sys.argv)
    treeview = TreeViewDialog()
    treeview.show()
    sys.exit(app.exec_())

if __name__ == '__main__':
    start()

지난번 탭 위젯의 두번째 탭에, QTableWidget을 사용해 테이블을 추가해 보도록 하겠습니다.

테이블의 데이터는 csv 파일로부터 읽도록 합니다.

결과 화면 : 

 

소스 코드 : 

TabWidgetB 클래스에 아래의 내용을 추가합니다.

  1. QTableWidget을 추가합니다.
    • setRowCount와 setColumnCount로 몇 행 몇 열의 테이블인지를 지정해 주어야 합니다.
      (데이터 파일의 총 line 수를 table의 rowCount로, 한 라인 안의 데이터 수를 table의 colCount로 설정합니다.)
    • setHorizontalHeaderLabels 로 테이블 헤더를 만들어 줍니다.
  2. csv 파일에서 데이터를 읽습니다. (,로 구분된 파일)
  3. 각 row, col에 읽은 데이터를 item으로 추가합니다. 
    • 아래에서는, (0,0) 셀부터 (2,2)셀까지 각 QTableWidgetItem을 만들어 추가해 주었습니다.
  4. 필요하다면, setStyleSheet으로 헤더와 각 셀의 스타일을 지정합니다.
# qt/tabwidget/TabWidget.py

class TabWidgetB(QWidget):
    def __init__(self):
        QWidget.__init__(self)
        self.tableWidget = QTableWidget(self)
        self.tableWidget.setMinimumSize(500, 200)
        self.tableWidget.setColumnCount(3)
        self.tableWidget.setHorizontalHeaderLabels(["header-1", "header-2", "header-3"])

        # read data from file
        # 경로는 본인 파일이 있는 경로로 설정
        # (main 함수가 있는 .py 파일 위치부터의 경로)
        with open('venv/qt/tabwidget/data/tab.csv', 'r', encoding='utf-8') as f:
            data = f.readlines()

        # Set data to tableWidget
        self.tableWidget.setRowCount(len(data))
        rowIdx = 0
        for line in data:
            cells = line.split(",")
            for colIdx in range(len(cells)):
                item = QTableWidgetItem(cells[colIdx])
                self.tableWidget.setItem(rowIdx, colIdx, item)
            rowIdx += 1

        self.tableWidget.setStyleSheet("QHeaderView::section {font-size:22px;}"
                                       "QTableWidget {font-size:22px;} "
                                       "QTableWidget::item{border-bottom:1px solid #fff; border-right:1px solid #fff;}")
        self.tableWidget.resizeColumnsToContents()
        self.tableWidget.resizeRowsToContents()

        vBox = QVBoxLayout(self)
        vBox.addWidget(self.tableWidget)
        self.setLayout(vBox)

 

아래는 탭 위젯에 사진 탭, 테이블 탭을 추가한 전체 소스코드 입니다.

1. qt/tabwidget/TabWidget.py

# qt/tabwidget/TabWidget.py

from PyQt5.QtWidgets import QApplication, QWidget, QLabel, QTabWidget, \
    QVBoxLayout, QScrollArea, QDialog, QTableWidget, QTableWidgetItem
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QPixmap

class TabDialog(QDialog):
    def __init__(self):
        QDialog.__init__(self)
        self.setWindowTitle("Tab Dialog")

        # Tab widget
        self.tabWidget = QTabWidget(self)
        self.tabWidget.addTab(TabWidgetA(), "tab1")
        self.tabWidget.addTab(TabWidgetB(), "tab2")
        self.tabWidget.setStyleSheet("QTabBar {font-size:30px;}")

        self.label = QLabel(self)
        self.label.setText("Title")
        self.label.setStyleSheet("font-size:40px; font-weight: bold;")
        self.label.setAlignment(Qt.AlignCenter)

        self.mainLayout = QVBoxLayout(self)
        self.mainLayout.addWidget(self.label, Qt.AlignHCenter)
        self.mainLayout.addWidget(self.tabWidget)
        self.setLayout(self.mainLayout)
        self.resize(600,400)


class TabWidgetA(QWidget):
    def __init__(self):
        QWidget.__init__(self)
        mainLayout = QVBoxLayout(self)

        self.label = QLabel(self)
        self.label.setText("Label text")

        self.scroll = QScrollArea(self)
        widget = QWidget()
        vBox = QVBoxLayout()
        for name in ('0001', '0002', '0003'):
            pixmap = QPixmap("venv/qt/tabwidget/data/{}.jpg".format(name))
            label = QLabel(self)
            label.setPixmap(pixmap)
            label.resize(pixmap.width(), pixmap.height())
            vBox.addWidget(label)
        widget.setLayout(vBox)
        self.scroll.setWidget(widget)
        self.scroll.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
        self.scroll.setWidgetResizable(True)

        mainLayout.addWidget(self.label)
        mainLayout.addWidget(self.scroll)
        self.setLayout(mainLayout)

class TabWidgetB(QWidget):
    def __init__(self):
        QWidget.__init__(self)
        self.tableWidget = QTableWidget(self)
        self.tableWidget.setMinimumSize(500, 200)
        self.tableWidget.setColumnCount(3)
        self.tableWidget.setHorizontalHeaderLabels(["header-1", "header-2", "header-3"])

        # read data from file
        with open('venv/qt/tabwidget/data/tab.csv', 'r', encoding='utf-8') as f:
            data = f.readlines()

        # Set data to tableWidget
        self.tableWidget.setRowCount(len(data))
        rowIdx = 0
        for line in data:
            cells = line.split(",")
            for colIdx in range(len(cells)):
                item = QTableWidgetItem(cells[colIdx])
                self.tableWidget.setItem(rowIdx, colIdx, item)
            rowIdx += 1

        self.tableWidget.setStyleSheet("QHeaderView::section {font-size:22px;}"
                                       "QTableWidget {font-size:22px;} "
                                       "QTableWidget::item{border-bottom:1px solid #fff; border-right:1px solid #fff;}")
        self.tableWidget.resizeColumnsToContents()
        self.tableWidget.resizeRowsToContents()

        vBox = QVBoxLayout(self)
        vBox.addWidget(self.tableWidget)
        self.setLayout(vBox)

2. main.py

# main.py

from qt.tabwidget.TabWidget import * # 본인의 소스파일이 있는 경로를 적고 import해주세요
import sys

def start():
    app = QApplication(sys.argv)
    tabDialog = TabDialog()
    tabDialog.show()
    sys.exit(app.exec_())

if __name__ == '__main__':
    start()

연결된 글 보기 :

[PyQt] Python에서 QTabWidget(탭 위젯) 사용하기

[PyQt] 스크롤 가능한 영역(ScrollArea)에 사진 추가하기

 

지난번 탭 다이얼로그에, 글자(라벨)와 사진 3장을 넣은 탭을 만들어 보도록 하겠습니다.

스크롤 바를 내려 아래 사진들을 더 볼 수 있게 합니다.

결과 화면 : 

소스 코드 :

지난번 TabWidgetA 클래스에 아래의 내용을 추가합니다.

  1. QLabel 로 텍스트를 추가합니다.
  2. QScrollArea를 만듭니다.
    • QScrollArea에 사진을 넣기 위해, 먼저 widget을 하나 만들어 줍니다.
    • widget에 그림(pixmap)을 추가해 줍니다.
    • widget을 QScrollArea에 붙입니다.
  3. QVBoxLayout에 위에서 만든 QLabel 과 QScrollArea를 추가합니다.
    (QVBoxLayout을 사용하는 이유는, 창 사이즈를 줄이거나/늘릴때 내용도 같이 동적으로 변하게 하기 위함)
class TabWidgetA(QWidget):
    def __init__(self):
        QWidget.__init__(self)
        mainLayout = QVBoxLayout(self)

        self.label = QLabel(self)
        self.label.setText("Label text")

        self.scroll = QScrollArea(self)
        widget = QWidget()
        vBox = QVBoxLayout()
        for name in ('0001', '0002', '0003'):        	
            # pixmap 경로는 본인의 사진 파일이 있는 경로를 사용
            # (main 함수가 있는 .py 파일의 위치부터의 경로)
            pixmap = QPixmap("venv/qt/tabwidget/data/{}.jpg".format(name))
            label = QLabel(self)
            label.setPixmap(pixmap)
            label.resize(pixmap.width(), pixmap.height())
            vBox.addWidget(label)
        widget.setLayout(vBox)
        self.scroll.setWidget(widget)
        self.scroll.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
        self.scroll.setWidgetResizable(True)

        mainLayout.addWidget(self.label)
        mainLayout.addWidget(self.scroll)
        self.setLayout(mainLayout)

 

연결된 글 보기 :

[PyQt] Python에서 QTabWidget(탭 위젯) 사용하기

다이얼로그 창에 탭을 추가하는 방법입니다.

결과 화면 : 

소스 코드 : 

1. QDialog를 상속받은 다이얼로그 클래스를 만들고, QTabWidget에 addTab()을 해서 각 탭을 추가합니다.

# TabWidget.py

from PyQt5.QtWidgets import QApplication, QWidget, QLabel, QTabWidget, \
    QVBoxLayout, QScrollArea, QDialog, QTableWidget, QTableWidgetItem
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QPixmap

class TabDialog(QDialog):
    def __init__(self):
        QDialog.__init__(self)
        self.setWindowTitle("Tab Dialog")

        # Tab widget
        self.tabWidget = QTabWidget(self)
        self.tabWidget.addTab(TabWidgetA(), "tab1")	# 탭1 추가 - 여기 적힌 내용이 탭 제목으로 보여짐
        self.tabWidget.addTab(TabWidgetB(), "tab2")	# 탭2 추가 - 여기 적힌 내용이 탭 제목으로 보여짐

        self.mainLayout = QVBoxLayout(self)
        self.mainLayout.addWidget(self.tabWidget)
        self.setLayout(self.mainLayout)
        self.resize(600,400)

 

2. 추가되는 각 탭에 들어가는 내용은 QWidget을 상속받은 클래스로 만들어 줍니다.

# TabWidget.py

class TabWidgetA(QWidget):
    def __init__(self):
        QWidget.__init__(self)
        # Do Something here...

class TabWidgetB(QWidget):
    def __init__(self):
        QWidget.__init__(self)
        # Do Something here...

 

3. 메인에서 TabDialog를 실행합니다. 

# main.py

def start():
    app = QApplication(sys.argv)
    tabDialog = TabDialog()
    tabDialog.show()
    sys.exit(app.exec_())

if __name__ == '__main__':
	import sys
    start()

 

4. 아래는 전체 소스코드 입니다.

from PyQt5.QtWidgets import QApplication, QWidget, QLabel, QTabWidget, \
    QVBoxLayout, QScrollArea, QDialog, QTableWidget, QTableWidgetItem
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QPixmap

class TabDialog(QDialog):
    def __init__(self):
        QDialog.__init__(self)
        self.setWindowTitle("Tab Dialog")

        # Tab widget
        self.tabWidget = QTabWidget(self)
        self.tabWidget.addTab(TabWidgetA(), "tab1")	# 탭1 추가 - 여기 적힌 내용이 탭 제목으로 보여짐
        self.tabWidget.addTab(TabWidgetB(), "tab2")	# 탭2 추가 - 여기 적힌 내용이 탭 제목으로 보여짐

        self.mainLayout = QVBoxLayout(self)
        self.mainLayout.addWidget(self.tabWidget)
        self.setLayout(self.mainLayout)
        self.resize(600,400)

class TabWidgetA(QWidget):
    def __init__(self):
        QWidget.__init__(self)
        # Do Something here...

class TabWidgetB(QWidget):
    def __init__(self):
        QWidget.__init__(self)
        # Do Something here...

def start():
    app = QApplication(sys.argv)
    tabDialog = TabDialog()
    tabDialog.show()
    sys.exit(app.exec_())

if __name__ == '__main__':
	import sys
    start()

 

다음 편에서는, 탭 위젯에

1. 스크롤 영역에 그림을 넣은 탭 (QScrollArea, QPixmap 사용)

2. csv 파일의 데이터를 읽어 테이블 형태로 보여주는 탭 (QTableWidget)

을 추가해 보도록 하겠습니다.

+ Recent posts