터미널에서 아래 명령을 실행하여 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
지난번 탭 위젯의 두번째 탭에, QTableWidget을 사용해 테이블을 추가해 보도록 하겠습니다.
테이블의 데이터는 csv 파일로부터 읽도록 합니다.
결과 화면 :
소스 코드 :
TabWidgetB 클래스에 아래의 내용을 추가합니다.
QTableWidget을 추가합니다.
setRowCount와 setColumnCount로 몇 행 몇 열의 테이블인지를 지정해 주어야 합니다. (데이터 파일의 총 line 수를 table의 rowCount로, 한 라인 안의 데이터 수를 table의 colCount로 설정합니다.)
setHorizontalHeaderLabels 로 테이블 헤더를 만들어 줍니다.
csv 파일에서 데이터를 읽습니다. (,로 구분된 파일)
각 row, col에 읽은 데이터를 item으로 추가합니다.
아래에서는, (0,0) 셀부터 (2,2)셀까지 각 QTableWidgetItem을 만들어 추가해 주었습니다.
필요하다면, 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()
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...