├── Projects
├── README.md
├── NotePad
│ ├── __init__.py
│ ├── notepad_i18n.pro
│ ├── notepad.ico
│ ├── translate
│ │ └── ko_KR.qm
│ ├── notepad_texteditor.py
│ └── notepad_statusbar.py
└── SceenCapture
│ ├── __init__.py
│ ├── v0
│ ├── __init__.py
│ └── capture.py
│ ├── v1
│ └── __init__.py
│ └── v2
│ └── __init__.py
├── .gitignore
├── QtFramework
├── README.md
├── Qt
│ ├── README.md
│ └── Internationalization
│ │ ├── i18n_01
│ │ ├── i18n.pro
│ │ └── i18n_01.py
│ │ └── i18n_02
│ │ ├── en_US.ts
│ │ ├── i18n.pro
│ │ └── i18n_02.py
├── QtGui
│ └── QPixmap
│ │ ├── apple.jpg
│ │ ├── QPixmap_00_basic.py
│ │ ├── QPixmap_05_crop.py
│ │ ├── QPixmap_04_image_to_base64.py
│ │ ├── QPixmap_02_render.py
│ │ ├── QPixmap_05_select_box.py
│ │ └── QPixmap_05_select_rubberband.py
├── QtWidgets
│ ├── QWidget
│ │ ├── shield.png
│ │ ├── sword.png
│ │ ├── QWidget_00_Form.py
│ │ ├── QWidget_06_Change_Icon.py
│ │ ├── QWidget_stack_high_lower.py
│ │ ├── QWidget_opacity.py
│ │ ├── QWidget_enter_leave_evnet.py
│ │ ├── QWidget_Find_Child_Widget.py
│ │ ├── QWidget_08_mouse_tracker.py
│ │ ├── QWidget_01_Properties.py
│ │ └── QWidget_02_Properties_PaintEvent.py
│ ├── QTabWidget
│ │ ├── plus_icon.png
│ │ ├── QTabWidget_00_basic.py
│ │ ├── QTabWidget_01_add_tab.py
│ │ └── QTabWidget_02_add_widget_in_tab.py
│ ├── QWebEngineView
│ │ ├── html
│ │ │ ├── snow.swf
│ │ │ ├── QWebEngineView_07_print_request.html
│ │ │ ├── QWebEngineView_08_alert.html
│ │ │ ├── QWebEngineView_06_close_request.html
│ │ │ ├── QWebEngineView_02_WebChannel.html
│ │ │ ├── QWebEngineView_09_WebChannelDataType.html
│ │ │ ├── QWebEngineView_10_plugin_enabled.html
│ │ │ ├── QWebEngineView_04_popup.html
│ │ │ └── QWebEngineView_05_download_request.html
│ │ ├── images
│ │ │ ├── go-next.png
│ │ │ ├── go-previous.png
│ │ │ ├── process-stop.png
│ │ │ ├── view-refresh.png
│ │ │ └── view-dom_tree.png
│ │ ├── qwebchannel.qrc
│ │ ├── js
│ │ │ ├── QWebEngineView_02_WebChannel.js
│ │ │ └── QWebEngineView_09_WebChannelDataType.js
│ │ ├── QWebEngineView_10_plugin_enabled.py
│ │ ├── QWebEngineView_00_basic.py
│ │ ├── QWebEngineView_06_close_request.py
│ │ ├── QWebEngineView_08_alert.py
│ │ ├── QWebEngineView_05_DownloadRequest.py
│ │ ├── QWebEngineView_02_WebChannel.py
│ │ ├── QWebEngineView_04_popup.py
│ │ └── QWebEngineView_07_print_request.py
│ ├── ItemViews_model_based
│ │ ├── shield.png
│ │ ├── sword.png
│ │ ├── assets
│ │ │ ├── earth.png
│ │ │ ├── mail.png
│ │ │ ├── mouse.png
│ │ │ ├── folder.png
│ │ │ ├── network.png
│ │ │ ├── calender.png
│ │ │ └── keyboard.png
│ │ ├── ItemViews_QListView_00_basic.py
│ │ ├── ItemViews_QTreeView_03_style.css
│ │ ├── ItemViews_QListView_01_user_list_model.py
│ │ ├── ItemViews_QTreeView_01_pixmap.py
│ │ ├── ItemViews_QTreeView_04_header.py
│ │ ├── ItemViews_QTreeView_00_basic.py
│ │ ├── ItemViews_QTreeView_05_header.py
│ │ ├── ItemViews_QListView_02_user_list_model.py
│ │ ├── ItemViews_QListView_03_user_list_model.py
│ │ └── ItemViews_QTreeView_03_style.py
│ ├── ItemWidget_Item_based
│ │ ├── ex.json
│ │ ├── ItemWidget_QListWidget_00_basic.py
│ │ ├── ItemWidget_QTreeWidget_00_basic.py
│ │ ├── ItemWidget_QTreeWidget_00_basic_2.py
│ │ ├── ItemWidget_QTreeWidget_01_column.py
│ │ ├── ItemWidget_QListWidget_01_widget_item.py
│ │ ├── ItemWidget_QTreeWidget_02_header.py
│ │ ├── ItemWidget_QTreeWidget_03_widget.py
│ │ ├── ItemWidget_QTreeWidget_05_properties_editor_trees.py
│ │ ├── ItemWidget_QTreeWidget_04_properties_editor.py
│ │ └── ItemWidget_QTreeWidget_06_move_to_other_widget.py
│ ├── QTextEdit
│ │ ├── QTextEdit_00_basic.py
│ │ └── QTextEdit_01_TextCursor.py
│ ├── QWizard
│ │ ├── QWizard_00_basic.py
│ │ ├── QWizard_01_is_completed.py
│ │ └── QWizard_02_is_completed.py
│ ├── Buttons
│ │ ├── Buttons_QPushButton_05_auto_repeat.py
│ │ ├── Buttons_QPushButton_02_toggle.py
│ │ ├── Buttons_QPushButton_00_basic.py
│ │ ├── Buttons_QCheckBox_00_basic.py
│ │ ├── Buttons_QPushButton_03_Pressed_Released_event.py
│ │ ├── Buttons_QRadioButton_00_basic.py
│ │ ├── Buttons_QPushButton_04_shortcut.py
│ │ ├── Buttons_QCheckBox_01_change_state.py
│ │ └── Buttons_QRadioButton_01_buttons_in_group.py
│ ├── QLineEdit
│ │ ├── QLineEdit_00_basic.py
│ │ ├── QLineEdit_02_completer.py
│ │ └── QLineEdit_01_input_mask.py
│ ├── QProgressBar
│ │ ├── QProgressBar_00_basic.py
│ │ └── QProgressBar_01_thread.py
│ ├── QFileDialLog
│ │ ├── QFileDialLog_00_basic.py
│ │ └── QFileDialLog_01_initial_display.py
│ ├── QDockWidget
│ │ └── QDockWidget_00_basic.py
│ ├── QComboBox
│ │ ├── QComboBox_00_basic.py
│ │ ├── QComboBox_01_model.py
│ │ ├── QComboBox_02_model_decoration.py
│ │ └── QComboBox_03_model_tableview.py
│ ├── Signal_Slot
│ │ ├── signal_slot_01_lambda.py
│ │ ├── signal_slot_00_basic.py
│ │ ├── signal_slot_04_custom_slot.py
│ │ ├── signal_slot_02_custom_signal.py
│ │ ├── signal_slot_05_custom_slot.py
│ │ ├── signal_slot_06_custom_slot.py
│ │ └── signal_slot_03_custom_signal.py
│ ├── QToolBar
│ │ ├── assets
│ │ │ ├── icon_split_horizontal.svg
│ │ │ └── icon_split_vertical.svg
│ │ ├── QToolBar_00_basic.py
│ │ └── QToolBar_01_sub_menu.py
│ ├── QLayout
│ │ ├── QLayout_00_Basic.py
│ │ ├── QLayout_01_Basic.py
│ │ ├── QLayout_02_complex_layout.py
│ │ └── QLayout_03_complex_layout.py
│ ├── Drag_and_Drop
│ │ ├── drag_and_drop_00_basic.py
│ │ ├── drag_and_drop_01_move_button.py
│ │ └── drag_and_drop_02_keep_feature.py
│ ├── QSplitter
│ │ ├── QSplitter_00_basic.py
│ │ └── QSplitter_01_tab_split.py
│ ├── GroupBox
│ │ └── QGroupBox_00_basic.py
│ ├── QLabel
│ │ └── QLabel_01_alignment.py
│ └── QStackedWidget
│ │ └── QStackedWidget_00_basic.py
└── QML
│ ├── 20-Layout
│ ├── 10-PyQt_QML_layout.qml
│ └── 10-PyQt_QML_layout.qml.autosave
│ ├── 10-PyQt_QML_basic
│ ├── 10-PyQt_QML_basic.qml
│ ├── 10-PyQt_QML_basic.py
│ ├── 11-PyQt_QML_javascript_in_QML.qml
│ └── 11-PyQt_QML_javascript_in_QML.py
│ └── 05-PyQt_QML_simple_examples
│ └── 10-PyQt_QML_simple_example.qml
├── README.md
└── Incompatibilities_with_Earlier_Versions
└── 5.5
├── Unhandled_Python_ Exceptions_00_reappearance.py
├── Unhandled_Python_ Exceptions_01_alternative.py
└── Unhandled_Python_ Exceptions_02_alternative.py
/Projects/README.md:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea
2 |
--------------------------------------------------------------------------------
/QtFramework/README.md:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Projects/NotePad/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/QtFramework/Qt/README.md:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Projects/SceenCapture/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Projects/SceenCapture/v0/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Projects/SceenCapture/v1/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Projects/SceenCapture/v2/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # OpenTutorials_PyQt
2 | 만들면서 배우는 PyQt 프로젝트 모음
3 |
--------------------------------------------------------------------------------
/Projects/NotePad/notepad_i18n.pro:
--------------------------------------------------------------------------------
1 | SOURCES += notepad.py notepad_menubar.py
2 | TRANSLATIONS += translate/ko_KR.ts
--------------------------------------------------------------------------------
/QtFramework/Qt/Internationalization/i18n_01/i18n.pro:
--------------------------------------------------------------------------------
1 | SOURCES += i18n_01.py
2 | TRANSLATIONS += translate/ko_KR.ts
--------------------------------------------------------------------------------
/Projects/NotePad/notepad.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RavenKyu/OpenTutorials_PyQt/HEAD/Projects/NotePad/notepad.ico
--------------------------------------------------------------------------------
/Projects/NotePad/translate/ko_KR.qm:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RavenKyu/OpenTutorials_PyQt/HEAD/Projects/NotePad/translate/ko_KR.qm
--------------------------------------------------------------------------------
/QtFramework/QtGui/QPixmap/apple.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RavenKyu/OpenTutorials_PyQt/HEAD/QtFramework/QtGui/QPixmap/apple.jpg
--------------------------------------------------------------------------------
/QtFramework/Qt/Internationalization/i18n_02/en_US.ts:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/QWidget/shield.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RavenKyu/OpenTutorials_PyQt/HEAD/QtFramework/QtWidgets/QWidget/shield.png
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/QWidget/sword.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RavenKyu/OpenTutorials_PyQt/HEAD/QtFramework/QtWidgets/QWidget/sword.png
--------------------------------------------------------------------------------
/QtFramework/Qt/Internationalization/i18n_02/i18n.pro:
--------------------------------------------------------------------------------
1 | SOURCES += i18n_02.py
2 | TRANSLATIONS += translate/ko_KR.ts translate/en_US.ts translate/ja_JP.ts
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/QTabWidget/plus_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RavenKyu/OpenTutorials_PyQt/HEAD/QtFramework/QtWidgets/QTabWidget/plus_icon.png
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/QWebEngineView/html/snow.swf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RavenKyu/OpenTutorials_PyQt/HEAD/QtFramework/QtWidgets/QWebEngineView/html/snow.swf
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/ItemViews_model_based/shield.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RavenKyu/OpenTutorials_PyQt/HEAD/QtFramework/QtWidgets/ItemViews_model_based/shield.png
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/ItemViews_model_based/sword.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RavenKyu/OpenTutorials_PyQt/HEAD/QtFramework/QtWidgets/ItemViews_model_based/sword.png
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/QWebEngineView/images/go-next.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RavenKyu/OpenTutorials_PyQt/HEAD/QtFramework/QtWidgets/QWebEngineView/images/go-next.png
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/ItemViews_model_based/assets/earth.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RavenKyu/OpenTutorials_PyQt/HEAD/QtFramework/QtWidgets/ItemViews_model_based/assets/earth.png
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/ItemViews_model_based/assets/mail.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RavenKyu/OpenTutorials_PyQt/HEAD/QtFramework/QtWidgets/ItemViews_model_based/assets/mail.png
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/ItemViews_model_based/assets/mouse.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RavenKyu/OpenTutorials_PyQt/HEAD/QtFramework/QtWidgets/ItemViews_model_based/assets/mouse.png
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/QWebEngineView/images/go-previous.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RavenKyu/OpenTutorials_PyQt/HEAD/QtFramework/QtWidgets/QWebEngineView/images/go-previous.png
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/QWebEngineView/images/process-stop.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RavenKyu/OpenTutorials_PyQt/HEAD/QtFramework/QtWidgets/QWebEngineView/images/process-stop.png
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/QWebEngineView/images/view-refresh.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RavenKyu/OpenTutorials_PyQt/HEAD/QtFramework/QtWidgets/QWebEngineView/images/view-refresh.png
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/ItemViews_model_based/assets/folder.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RavenKyu/OpenTutorials_PyQt/HEAD/QtFramework/QtWidgets/ItemViews_model_based/assets/folder.png
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/ItemViews_model_based/assets/network.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RavenKyu/OpenTutorials_PyQt/HEAD/QtFramework/QtWidgets/ItemViews_model_based/assets/network.png
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/QWebEngineView/images/view-dom_tree.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RavenKyu/OpenTutorials_PyQt/HEAD/QtFramework/QtWidgets/QWebEngineView/images/view-dom_tree.png
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/QWebEngineView/qwebchannel.qrc:
--------------------------------------------------------------------------------
1 |
2 |
3 | js/qwebchannel.js
4 |
5 |
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/ItemViews_model_based/assets/calender.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RavenKyu/OpenTutorials_PyQt/HEAD/QtFramework/QtWidgets/ItemViews_model_based/assets/calender.png
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/ItemViews_model_based/assets/keyboard.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RavenKyu/OpenTutorials_PyQt/HEAD/QtFramework/QtWidgets/ItemViews_model_based/assets/keyboard.png
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/QWebEngineView/html/QWebEngineView_07_print_request.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Click the button to print this window.
6 |
7 |
8 |
9 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/QWebEngineView/html/QWebEngineView_08_alert.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Click the button to print this window.
6 |
7 |
8 |
9 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/QWebEngineView/html/QWebEngineView_06_close_request.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Click the button to close this window.
6 |
7 |
8 |
9 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/QWebEngineView/html/QWebEngineView_02_WebChannel.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Title
6 |
7 |
8 |
9 |
10 | Hello PyQt
11 |
12 |
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/QWebEngineView/html/QWebEngineView_09_WebChannelDataType.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Title
6 |
7 |
8 |
9 |
10 | Hello PyQt
11 |
12 |
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/QWebEngineView/html/QWebEngineView_10_plugin_enabled.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Title
6 |
7 |
8 |
9 |
10 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/QWebEngineView/js/QWebEngineView_02_WebChannel.js:
--------------------------------------------------------------------------------
1 | new QWebChannel(qt.webChannelTransport, function (channel) {
2 | handler = channel.objects.handler;
3 | handler.setText("Hello"); // 연결되자마자 Hello를 쏜다
4 |
5 | // handler 시그널인 getText와 연결
6 | handler.getText.connect(function(message) {
7 | console.log("Received message: " + message);
8 | handler.setText("Succeed")
9 | });
10 |
11 | });
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/QWebEngineView/html/QWebEngineView_04_popup.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Click the button to open an about:blank page in a new browser window that is 200px wide and 100px tall.
6 |
7 |
8 |
9 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/QtFramework/QML/20-Layout/10-PyQt_QML_layout.qml:
--------------------------------------------------------------------------------
1 | import QtQuick 2.9
2 | import QtQuick.Controls 2.2
3 | import QtQuick.Window 2.3
4 |
5 | Rectangle {
6 | width: 200; height: 200
7 | Text {
8 | x: 6
9 | y: 55
10 | width: 188
11 | height: 90
12 | text: "Hello PyQt, QML."
13 | font.pointSize: 14
14 | font.family: "Verdana"
15 | horizontalAlignment: Text.AlignHCenter
16 | verticalAlignment: Text.AlignVCenter
17 |
18 | }
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/QtFramework/QML/10-PyQt_QML_basic/10-PyQt_QML_basic.qml:
--------------------------------------------------------------------------------
1 | import QtQuick 2.9
2 | import QtQuick.Controls 2.2
3 | import QtQuick.Window 2.3
4 |
5 | Rectangle {
6 | width: 200; height: 200
7 | Text {
8 | x: 6
9 | y: 55
10 | width: 188
11 | height: 90
12 | text: "Hello PyQt, QML."
13 | font.pointSize: 14
14 | font.family: "Verdana"
15 | horizontalAlignment: Text.AlignHCenter
16 | verticalAlignment: Text.AlignVCenter
17 |
18 | }
19 |
20 | }
21 |
--------------------------------------------------------------------------------
/Projects/NotePad/notepad_texteditor.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding: utf-8
3 |
4 | # 예제 내용
5 | # 윈도우 메모장(NotePad) 만들기
6 |
7 |
8 | from PyQt5.QtWidgets import QTextEdit
9 | from PyQt5.QtCore import Qt
10 |
11 | __author__ = "Deokyu Lim "
12 |
13 |
14 | class TextEditor(QTextEdit):
15 | def __init__(self):
16 | QTextEdit.__init__(self)
17 |
18 | if __name__ == "__main__":
19 | import sys
20 | from PyQt5.QtWidgets import QApplication
21 | app = QApplication(sys.argv)
22 | form = TextEditor()
23 | form.show()
24 | exit(app.exec_())
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/ItemWidget_Item_based/ex.json:
--------------------------------------------------------------------------------
1 | {
2 | "metadata": {
3 | "version": [1, 0, 1, "b"],
4 | "data_type": "scenario",
5 | "title": "LinkedIn Test Scenario",
6 | "related_date": {
7 | "created": 1520413079,
8 | "last_modified": 1520413079},
9 | "related_people": {
10 | "author": {
11 | "name": "Raven",
12 | "email": "deokyu@vivans.net"
13 | },
14 | "last_modified_by": {
15 | "name": "Jerry",
16 | "emil": "mcchae@vivans.net"
17 | }
18 | },
19 | "comment": "LinkedIn RPA Scenario"
20 | },
21 | }
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/QWebEngineView/js/QWebEngineView_09_WebChannelDataType.js:
--------------------------------------------------------------------------------
1 | new QWebChannel(qt.webChannelTransport, function (channel) {
2 | handler = channel.objects.handler;
3 | handler.webToAppSendData({"data": ["hello", "world", 1, {"A": true, "B": false}]});
4 |
5 | handler.appToWebSendData.connect(function(value) {
6 | console.log(value);
7 | handler.webToAppSendData(
8 | {"data": ["hello", "world", 1, {"A": true, "B": false}]});
9 | handler.webToAppSendData(
10 | [1, true, false, {"a": "b"}])
11 | });
12 |
13 | });
14 |
15 |
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/QWebEngineView/html/QWebEngineView_05_download_request.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Click the button to request for downloading a file.
6 |
7 |
8 |
9 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/QtFramework/QML/10-PyQt_QML_basic/10-PyQt_QML_basic.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | # 예제 내용
4 | # * QML 을 이용한 GUI 프로그래밍
5 |
6 | __author__ = "Deokyu Lim "
7 |
8 | from PyQt5.QtCore import QUrl
9 | from PyQt5.QtQuick import QQuickView
10 | from PyQt5.QtWidgets import QApplication
11 | import sys
12 |
13 |
14 | class MainWindow(QQuickView):
15 | def __init__(self):
16 | super().__init__()
17 | self.setSource(QUrl.fromLocalFile('10-PyQt_QML_basic.qml'))
18 | self.rootContext().setContextProperty("MainWindow", self)
19 | self.show()
20 |
21 |
22 | if __name__ == '__main__':
23 | app = QApplication(sys.argv)
24 | w = MainWindow()
25 | sys.exit(app.exec_())
--------------------------------------------------------------------------------
/QtFramework/QML/10-PyQt_QML_basic/11-PyQt_QML_javascript_in_QML.qml:
--------------------------------------------------------------------------------
1 | import QtQuick 2.9
2 | import QtQuick.Controls 2.2
3 | import QtQuick.Window 2.3
4 |
5 | Item{
6 | Rectangle{
7 | id: mainWindow
8 | objectName: "mainWindow"
9 | visible: true
10 | width: 400
11 | height: 400
12 | color: "#000000"
13 |
14 | MouseArea {
15 | anchors.fill: parent
16 | onClicked: {
17 | console.log("Mouse clicked!", parent.color)
18 | if (parent.color == "#000000")
19 | parent.color = 'blue';
20 | else
21 | parent.color = 'black';
22 | }
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/QtFramework/QML/10-PyQt_QML_basic/11-PyQt_QML_javascript_in_QML.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | # 예제 내용
4 | # * QML 을 이용한 GUI 프로그래밍
5 | # * QML 안에서 자바스크립 사용하기
6 |
7 | __author__ = "Deokyu Lim "
8 |
9 | from PyQt5.QtCore import QUrl
10 | from PyQt5.QtQuick import QQuickView
11 | from PyQt5.QtWidgets import QApplication
12 | import sys
13 |
14 |
15 | class MainWindow(QQuickView):
16 | def __init__(self):
17 | super().__init__()
18 | self.setSource(QUrl.fromLocalFile('11-PyQt_QML_javascript_in_QML.qml'))
19 | self.rootContext().setContextProperty("MainWindow", self)
20 | self.root = self.rootObject()
21 |
22 | self.show()
23 |
24 |
25 | if __name__ == '__main__':
26 | app = QApplication(sys.argv)
27 | w = MainWindow()
28 | sys.exit(app.exec_())
--------------------------------------------------------------------------------
/Incompatibilities_with_Earlier_Versions/5.5/Unhandled_Python_ Exceptions_00_reappearance.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding: utf-8
3 |
4 | # 예제 내용
5 | # C++ 로 바인딩된 코드 사용중 에러 발생시 Traceback 안되는 상황 재현
6 |
7 | import sys
8 |
9 | from PyQt5.QtWidgets import QApplication
10 | from PyQt5.QtWidgets import QPushButton
11 | from PyQt5.QtCore import pyqtSlot
12 |
13 | __author__ = "Deokyu Lim "
14 |
15 |
16 | class Form(QPushButton):
17 | def __init__(self):
18 | QPushButton.__init__(self)
19 | self.setText("Click to raise error")
20 | self.clicked.connect(self.error)
21 |
22 | @pyqtSlot()
23 | def error(self):
24 | raise RuntimeError
25 |
26 | if __name__ == "__main__":
27 | app = QApplication(sys.argv)
28 | form = Form()
29 | form.show()
30 | exit(app.exec_())
31 |
--------------------------------------------------------------------------------
/Projects/NotePad/notepad_statusbar.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding: utf-8
3 |
4 | from PyQt5.QtWidgets import QStatusBar
5 | from PyQt5.QtGui import QTextCursor
6 | from PyQt5.QtCore import pyqtSlot
7 |
8 |
9 | class StatusBar(QStatusBar):
10 | @pyqtSlot(QTextCursor)
11 | def __init__(self):
12 | QStatusBar.__init__(self)
13 | self.setVisible(False)
14 |
15 | def change_cursor_info(self, data:QTextCursor):
16 | ss = data.selectionStart()
17 | se = data.selectionEnd()
18 |
19 | selected_info = ""
20 | if se - ss:
21 | selected_info = "{0} {1} ".format(se - ss, "char" if (se-ss) == 1 else "chars")
22 | self.showMessage("{0}{1}:{2}".format(
23 | selected_info,
24 | data.blockNumber(),
25 | data.columnNumber())
26 | )
27 |
28 |
--------------------------------------------------------------------------------
/Incompatibilities_with_Earlier_Versions/5.5/Unhandled_Python_ Exceptions_01_alternative.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding: utf-8
3 |
4 | # 예제 내용
5 | # C++ 로 바인딩된 코드 사용중 에러 발생시 Traceback 안되는 상황 재현 및 처리
6 |
7 | import sys
8 |
9 | from PyQt5.QtWidgets import QApplication
10 | from PyQt5.QtWidgets import QPushButton
11 | from PyQt5.QtCore import pyqtSlot
12 |
13 | __author__ = "Deokyu Lim "
14 |
15 |
16 | class Form(QPushButton):
17 | def __init__(self):
18 | QPushButton.__init__(self)
19 | self.setText("Click to raise error")
20 | self.clicked.connect(self.error)
21 |
22 | @pyqtSlot()
23 | def error(self):
24 | raise RuntimeError
25 |
26 | if __name__ == "__main__":
27 | # 예외 훅을 재설정.
28 | excepthook = sys.excepthook
29 | sys.excepthook = lambda t, val, tb: excepthook(t, val, tb)
30 |
31 | app = QApplication(sys.argv)
32 | form = Form()
33 | form.show()
34 | exit(app.exec_())
35 |
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/QTextEdit/QTextEdit_00_basic.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding: utf-8
3 |
4 | # 예제 내용
5 | # * 기본 위젯을 사용하여 기본 창을 생성
6 | # * '창 이름'을 변경한다.
7 |
8 | import sys
9 |
10 | from PyQt5.QtWidgets import QWidget
11 | from PyQt5.QtWidgets import QTextEdit
12 | from PyQt5.QtWidgets import QApplication
13 | from PyQt5.QtWidgets import QBoxLayout
14 | from PyQt5.QtCore import Qt
15 |
16 | __author__ = "Deokyu Lim "
17 |
18 |
19 | class Form(QWidget):
20 | def __init__(self):
21 | QWidget.__init__(self, flags=Qt.Widget)
22 | self.init_widget()
23 |
24 | def init_widget(self):
25 | self.setWindowTitle("Hello World")
26 | form_lbx = QBoxLayout(QBoxLayout.TopToBottom, parent=self)
27 | self.setLayout(form_lbx)
28 |
29 | te = QTextEdit()
30 |
31 | form_lbx.addWidget(te)
32 |
33 | if __name__ == "__main__":
34 | app = QApplication(sys.argv)
35 | form = Form()
36 | form.show()
37 | exit(app.exec_())
38 |
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/QWizard/QWizard_00_basic.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding: utf-8
3 |
4 | # 예제 내용
5 | # QWizard 사용 예제
6 |
7 |
8 | import sys
9 |
10 | from PyQt5.QtWidgets import QWizard
11 | from PyQt5.QtWidgets import QWizardPage
12 | from PyQt5.QtWidgets import QApplication
13 | from PyQt5.QtCore import Qt
14 |
15 | __author__ = "Deokyu Lim "
16 |
17 | class Start(QWizardPage):
18 | def __init__(self):
19 | QWizardPage.__init__(self)
20 | self.setTitle("Start Page")
21 | self.setSubTitle("Sub Start Page")
22 |
23 |
24 | class Form(QWizard):
25 | def __init__(self):
26 | QWizard.__init__(self, flags=Qt.Widget)
27 | self.init_widget()
28 | self.init_pages()
29 |
30 | def init_pages(self):
31 | self.addPage(Start())
32 |
33 | def init_widget(self):
34 | self.setWindowTitle("Hello World")
35 |
36 |
37 | if __name__ == "__main__":
38 | app = QApplication(sys.argv)
39 | form = Form()
40 | form.show()
41 | exit(app.exec_())
42 |
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/QWidget/QWidget_00_Form.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding: utf-8
3 |
4 | # 예제 내용
5 | # * 기본 위젯을 사용하여 기본 창을 생성
6 | # * '창 이름'을 변경한다.
7 |
8 | import sys
9 |
10 | from PyQt5.QtWidgets import QWidget
11 | from PyQt5.QtWidgets import QApplication
12 | from PyQt5.QtCore import Qt
13 |
14 | __author__ = "Deokyu Lim "
15 |
16 |
17 | class Form(QWidget):
18 | """
19 | 만들고자 하는 프로그램의 기본이 되는 창 또는 폼 위젯.
20 | 본 위젯 위에 다른 위젯을 올려서 모양을 만든다.
21 |
22 | QWidget을 상속받아서 필요한 메소드를 작성.
23 | """
24 |
25 | def __init__(self):
26 | """
27 | 보통 __init__ (생성자)에서 필요한 것들을 다를 위젯들을 선언해줘도 되지만 init_widget을 따로 만들어서 호출한다.
28 | """
29 | QWidget.__init__(self, flags=Qt.Widget)
30 | self.init_widget()
31 |
32 | def init_widget(self):
33 | """
34 | 현재 위젯의 모양등을 초기화
35 | """
36 | self.setWindowTitle("Hello World")
37 |
38 | if __name__ == "__main__":
39 | app = QApplication(sys.argv)
40 | form = Form()
41 | form.show()
42 | exit(app.exec_())
43 |
--------------------------------------------------------------------------------
/QtFramework/QtGui/QPixmap/QPixmap_00_basic.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding: utf-8
3 |
4 | # 예제 내용
5 | # * QPixmap사용
6 |
7 | import sys
8 | from PyQt5.QtWidgets import QWidget
9 | from PyQt5.QtWidgets import QLabel
10 | from PyQt5.QtWidgets import QBoxLayout
11 | from PyQt5.QtWidgets import QApplication
12 | from PyQt5.QtGui import QPixmap
13 |
14 | __author__ = "Deokyu Lim "
15 |
16 |
17 | class Window(QWidget):
18 | def __init__(self):
19 | QWidget.__init__(self)
20 | self.lb_1 = QLabel()
21 | self.init_ui()
22 |
23 | def init_ui(self):
24 | self.setMinimumWidth(320)
25 | self.setMinimumHeight(240)
26 | layout = QBoxLayout(QBoxLayout.TopToBottom)
27 | self.setLayout(layout)
28 | pixmap = QPixmap("apple.jpg")
29 | pixmap = pixmap.scaledToHeight(240) # 사이즈가 조정
30 | self.lb_1.setPixmap(pixmap)
31 |
32 | layout.addWidget(self.lb_1)
33 |
34 | if __name__ == "__main__":
35 | app = QApplication(sys.argv)
36 | form = Window()
37 | form.show()
38 | exit(app.exec_())
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/Buttons/Buttons_QPushButton_05_auto_repeat.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding: utf-8
3 |
4 | # 예제 내용
5 | # * 설정된 인터벌을 참고하여 주기적 pressed 시그널 발생
6 |
7 | import sys
8 |
9 | from PyQt5.QtWidgets import QPushButton
10 | from PyQt5.QtWidgets import QApplication
11 | from PyQt5.QtCore import pyqtSlot
12 |
13 | __author__ = "Deokyu Lim "
14 |
15 |
16 | class Button(QPushButton):
17 | def __init__(self):
18 | QPushButton.__init__(self, "0")
19 | self.setFixedSize(100, 100)
20 |
21 | # 주기적으로 pressed 시그널 발생
22 | # 밀리세컨드 단위로 인터벌 조정 가능
23 | self.setAutoRepeatInterval(10)
24 | self.setAutoRepeat(True)
25 | self.click_cnt = 0
26 |
27 | self.pressed.connect(self._pressed)
28 | #
29 | @pyqtSlot()
30 | def _pressed(self):
31 | """
32 | 클릭 수를 카운터하여 표출
33 | """
34 | self.click_cnt += 1
35 | self.setText(str(self.click_cnt))
36 |
37 | if __name__ == "__main__":
38 | app = QApplication(sys.argv)
39 | form = Button()
40 | form.show()
41 | exit(app.exec_())
42 |
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/QWebEngineView/QWebEngineView_10_plugin_enabled.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding: utf-8
3 |
4 | # 예제 내용
5 | # * QWebEngineView 창 닫기 요구
6 |
7 | import sys
8 |
9 | from PyQt5.QtWidgets import QApplication
10 | from PyQt5.QtCore import QDir
11 | from PyQt5.QtCore import QUrl
12 | from PyQt5.QtWebEngineWidgets import QWebEngineView
13 | from PyQt5.QtWebEngineWidgets import QWebEngineSettings
14 |
15 | __author__ = "Deokyu Lim "
16 |
17 |
18 | class WebView(QWebEngineView):
19 | def __init__(self):
20 | QWebEngineView.__init__(self)
21 |
22 | # Flash 등을 사용하기 위해서 Plugin 사용을 허락
23 | QWebEngineSettings.globalSettings().setAttribute(
24 | QWebEngineSettings.PluginsEnabled, True);
25 |
26 | # 로컬파일 사용시 절대경로만 사용해야 함
27 | url = QDir().current().filePath(
28 | "html/QWebEngineView_10_plugin_enabled.html")
29 | url = QUrl.fromLocalFile(url)
30 | self.setUrl(url)
31 |
32 |
33 | if __name__ == "__main__":
34 | app = QApplication(sys.argv)
35 | form = WebView()
36 | form.show()
37 | exit(app.exec_())
38 |
--------------------------------------------------------------------------------
/QtFramework/QML/20-Layout/10-PyQt_QML_layout.qml.autosave:
--------------------------------------------------------------------------------
1 | import QtQuick 2.9
2 | import QtQuick.Controls 2.2
3 | import QtQuick.Window 2.3
4 | import QtQuick.Layouts 1.3
5 |
6 | Rectangle {
7 | id: rectangle
8 | width: 300; height: 300
9 |
10 | ColumnLayout {
11 | id: columnLayout
12 | transformOrigin: Item.Center
13 | anchors.fill: parent
14 |
15 | RowLayout {
16 | id: rowLayout
17 | width: 284
18 | height: 173
19 | Layout.fillWidth: true
20 | }
21 |
22 | Button {
23 | id: button
24 | width: 284
25 | height: 40
26 | text: qsTr("Button")
27 | Layout.fillWidth: true
28 | Layout.alignment: Qt.AlignHCenter | Qt.AlignVCenter
29 |
30 | }
31 |
32 | Button {
33 | id: button1
34 | width: 284
35 | height: 40
36 | text: qsTr("Button")
37 | Layout.fillWidth: true
38 |
39 | }
40 |
41 |
42 | }
43 |
44 |
45 |
46 | }
47 |
--------------------------------------------------------------------------------
/QtFramework/Qt/Internationalization/i18n_01/i18n_01.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding: utf-8
3 |
4 | # 예제 내용
5 | # i18n 을 위한 예제
6 | # 창의 기본 이름이 Hello World지만 한국어 사용일 경우 안녕 세계가 뜨로록 한다.
7 | # * '창 이름'을 변경한다.
8 |
9 | import sys
10 |
11 | from PyQt5.QtWidgets import QWidget
12 | from PyQt5.QtWidgets import QApplication
13 | from PyQt5.QtCore import QTranslator
14 | from PyQt5.QtCore import Qt
15 | from PyQt5.QtCore import QLocale
16 |
17 | __author__ = "Deokyu Lim "
18 |
19 |
20 | class Form(QWidget):
21 | def __init__(self):
22 | QWidget.__init__(self, flags=Qt.Widget)
23 | self.init_widget()
24 |
25 | def init_widget(self):
26 | self.setWindowTitle(self.tr("Hello World"))
27 |
28 | if __name__ == "__main__":
29 | app = QApplication(sys.argv)
30 |
31 | # 다국어 지원
32 | translator = QTranslator()
33 | translator.load("translate\ko_KR.qm")
34 |
35 | # 현재 시스템 로케일 이름을 출력
36 | tr_path = "translate\\" + QLocale.system().name() + ".qm"
37 | print(tr_path)
38 | # translator.load(tr_path) # 여기선 사용하지 않으므로 주석
39 |
40 | app.installTranslator(translator)
41 |
42 | form = Form()
43 | form.show()
44 | exit(app.exec_())
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/ItemViews_model_based/ItemViews_QListView_00_basic.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding: utf-8
3 |
4 | # 예제 내용
5 | # * QListView 기본 사용법
6 | # * QStandardItemModel과 QStandardItem 이용
7 |
8 | import sys
9 |
10 | from PyQt5.QtWidgets import QWidget
11 | from PyQt5.QtWidgets import QListView
12 | from PyQt5.QtGui import QStandardItemModel
13 | from PyQt5.QtGui import QStandardItem
14 |
15 | from PyQt5.QtWidgets import QApplication
16 | from PyQt5.QtCore import Qt
17 |
18 | __author__ = "Deokyu Lim "
19 |
20 |
21 | class Form(QWidget):
22 | def __init__(self):
23 | QWidget.__init__(self, flags=Qt.Widget)
24 | self.setWindowTitle("ItemView QListView")
25 | self.setFixedHeight(100)
26 |
27 | fruits = ["banana", "apple", "melon", "pear"]
28 |
29 | view = QListView(self)
30 | model = QStandardItemModel()
31 | for f in fruits:
32 | model.appendRow(QStandardItem(f))
33 | view.setModel(model)
34 |
35 | if __name__ == "__main__":
36 | app = QApplication(sys.argv)
37 | form = Form()
38 | form.show()
39 | exit(app.exec_())
40 |
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/QTabWidget/QTabWidget_00_basic.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding: utf-8
3 |
4 | # 예제 내용
5 | # * QTabWidget 기본 사용
6 |
7 | import sys
8 |
9 | from PyQt5.QtWidgets import QWidget
10 | from PyQt5.QtWidgets import QBoxLayout
11 | from PyQt5.QtWidgets import QTextEdit
12 | from PyQt5.QtWidgets import QTabWidget
13 | from PyQt5.QtWidgets import QApplication
14 | from PyQt5.QtCore import Qt
15 |
16 | __author__ = "Deokyu Lim "
17 |
18 |
19 | class Form(QWidget):
20 | def __init__(self):
21 | QWidget.__init__(self, flags=Qt.Widget)
22 | self.init_widget()
23 |
24 | def init_widget(self):
25 | """
26 | 현재 위젯의 모양등을 초기화
27 | """
28 | self.setWindowTitle("Tab Widget")
29 | form_lbx = QBoxLayout(QBoxLayout.TopToBottom, parent=self)
30 | self.setLayout(form_lbx)
31 |
32 | tbw = QTabWidget()
33 | form_lbx.addWidget(tbw)
34 |
35 | # 탭 추가
36 | tbw.addTab(QTextEdit(), "Tab #1")
37 |
38 | if __name__ == "__main__":
39 | app = QApplication(sys.argv)
40 | form = Form()
41 | form.show()
42 | exit(app.exec_())
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/QWebEngineView/QWebEngineView_00_basic.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding: utf-8
3 |
4 | # 예제 내용
5 | # * QWebEngineView를 이용한 웹 위젯 사용
6 |
7 | import sys
8 |
9 | from PyQt5.QtWidgets import QWidget
10 | from PyQt5.QtWidgets import QBoxLayout
11 |
12 | from PyQt5.QtWidgets import QApplication
13 | from PyQt5.QtCore import Qt
14 |
15 | from PyQt5.QtWebEngineWidgets import QWebEngineView
16 | from PyQt5.QtCore import QUrl
17 |
18 | __author__ = "Deokyu Lim "
19 |
20 |
21 | class Form(QWidget):
22 | def __init__(self):
23 | QWidget.__init__(self, flags=Qt.Widget)
24 | self.form_layout = QBoxLayout(QBoxLayout.LeftToRight, self)
25 | self.setLayout(self.form_layout)
26 | self.init_widget()
27 |
28 | def init_widget(self):
29 | self.setWindowTitle("QWebEngineView")
30 | # QWebEngineView 를 이용하여 웹 페이지를 표출
31 | web = QWebEngineView()
32 | web.setUrl(QUrl("https://www.google.com"))
33 | self.form_layout.addWidget(web)
34 |
35 |
36 | if __name__ == "__main__":
37 | app = QApplication(sys.argv)
38 | form = Form()
39 | form.show()
40 | exit(app.exec_())
41 |
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/ItemWidget_Item_based/ItemWidget_QListWidget_00_basic.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding: utf-8
3 |
4 | # 예제 내용
5 | # * QListWidget을 사용하여 아이템을 표시
6 |
7 | __author__ = "Deokyu Lim "
8 |
9 | from PyQt5.QtWidgets import QWidget
10 | from PyQt5.QtWidgets import QListWidgetItem
11 | from PyQt5.QtCore import QVariant
12 | from PyQt5.QtWidgets import QListWidget
13 | from PyQt5.QtWidgets import QApplication
14 | from PyQt5.QtCore import Qt
15 |
16 |
17 | class Form(QWidget):
18 | def __init__(self):
19 | QWidget.__init__(self, flags=Qt.Widget)
20 | self.setWindowTitle("QTreeWidget")
21 | self.setFixedWidth(210)
22 | self.setFixedHeight(150)
23 |
24 | # QTreeView 생성 및 설정
25 | self.viewer = QListWidget(self)
26 | item = QListWidgetItem()
27 | item.setText( "Fruit")
28 | self.viewer.addItem(item)
29 | item = QListWidgetItem()
30 | item.setText("Vegetable")
31 | self.viewer.addItem(item)
32 |
33 |
34 | if __name__ == "__main__":
35 | import sys
36 | app = QApplication(sys.argv)
37 | form = Form()
38 | form.show()
39 | exit(app.exec_())
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/Buttons/Buttons_QPushButton_02_toggle.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding: utf-8
3 |
4 | # 예제 내용
5 | # * 토클 버튼의 사용법을 알아본다
6 |
7 |
8 | import sys
9 |
10 | from PyQt5.QtWidgets import QPushButton
11 | from PyQt5.QtWidgets import QApplication
12 | from PyQt5.QtCore import pyqtSlot
13 |
14 | __author__ = "Deokyu Lim "
15 |
16 |
17 | class Button(QPushButton):
18 | """
19 | QPushButton 은 QWidget을 상속받고 있으므로 단일 창으로 표출 가능
20 | """
21 | def __init__(self):
22 | QPushButton.__init__(self, "OFF")
23 | self.setFixedSize(100, 100)
24 | self.setStyleSheet("background-color: red")
25 |
26 | self.setCheckable(True)
27 | self.toggled.connect(self.slot_toggle)
28 |
29 | @pyqtSlot(bool)
30 | def slot_toggle(self, state):
31 | """
32 | toggle 상태에 따라 배경색과 상태 텍스트 변환
33 | """
34 | self.setStyleSheet("background-color: %s" % ({True: "green", False: "red"}[state]))
35 | self.setText({True: "ON", False: "OFF"}[state])
36 |
37 | if __name__ == "__main__":
38 | app = QApplication(sys.argv)
39 | form = Button()
40 | form.show()
41 | exit(app.exec_())
42 |
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/QWebEngineView/QWebEngineView_06_close_request.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding: utf-8
3 |
4 | # 예제 내용
5 | # * QWebEngineView 창 닫기 요구
6 |
7 | import sys
8 |
9 | from PyQt5.QtWidgets import QApplication
10 | from PyQt5.QtCore import QDir
11 | from PyQt5.QtCore import QUrl
12 | from PyQt5.QtWebEngineWidgets import QWebEngineView
13 | from PyQt5.QtWebEngineWidgets import QWebEngineSettings
14 |
15 | __author__ = "Deokyu Lim "
16 |
17 |
18 | class WebView(QWebEngineView):
19 | def __init__(self):
20 | QWebEngineView.__init__(self)
21 | self.settings().setAttribute(
22 | QWebEngineSettings.JavascriptCanOpenWindows, True)
23 | # QWebEnginePage에서 windowsCloseRequest를 가지고 있다.
24 | self.page().windowCloseRequested.connect(self.close)
25 |
26 | # 로컬파일 사용시 절대경로만 사용해야 함
27 | url = QDir().current().filePath(
28 | "html/QWebEngineView_06_close_request.html")
29 | url = QUrl.fromLocalFile(url)
30 | self.setUrl(url)
31 |
32 |
33 | if __name__ == "__main__":
34 | app = QApplication(sys.argv)
35 | form = WebView()
36 | form.show()
37 | exit(app.exec_())
38 |
--------------------------------------------------------------------------------
/Incompatibilities_with_Earlier_Versions/5.5/Unhandled_Python_ Exceptions_02_alternative.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding: utf-8
3 |
4 | # 예제 내용
5 | # C++ 로 바인딩된 코드 사용중 에러 발생시 Traceback 안되는 상황 재현 및 처리
6 | # 메세지박스를 이용하여 에러 상황 전달
7 |
8 | import sys
9 |
10 | from PyQt5.QtWidgets import QApplication
11 | from PyQt5.QtWidgets import QPushButton
12 | from PyQt5.QtWidgets import QMessageBox
13 | from PyQt5.QtCore import pyqtSlot
14 |
15 | __author__ = "Deokyu Lim "
16 |
17 |
18 | class Form(QPushButton):
19 | def __init__(self):
20 | QPushButton.__init__(self)
21 | self.setText("Click to raise error")
22 | self.clicked.connect(self.error)
23 |
24 | @pyqtSlot()
25 | def error(self):
26 | raise RuntimeError
27 |
28 | def exception_hook(t, val, tb):
29 | QMessageBox.critical(None, "An exception was raised", "Exception type: {}".format(t))
30 | old_exception_hook(t, val, tb)
31 |
32 | if __name__ == "__main__":
33 | # 예외 훅을 재설정.
34 | old_exception_hook = sys.excepthook
35 | sys.excepthook = exception_hook
36 |
37 | app = QApplication(sys.argv)
38 | form = Form()
39 | form.show()
40 | exit(app.exec_())
41 |
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/Buttons/Buttons_QPushButton_00_basic.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding: utf-8
3 |
4 | # 예제 내용
5 | # * 버튼의 기본 사용법을 알아본다
6 | # * '창 이름'을 변경한다.
7 |
8 | import sys
9 |
10 | from PyQt5.QtWidgets import QPushButton
11 | from PyQt5.QtWidgets import QApplication
12 | from PyQt5.QtCore import pyqtSlot
13 |
14 | __author__ = "Deokyu Lim "
15 |
16 |
17 | class Button(QPushButton):
18 | """
19 | QPushButton 은 QWidget을 상속받고 있으므로 단일 창으로 표출 가능
20 | """
21 | def __init__(self):
22 | QPushButton.__init__(self, "0")
23 | self.setFixedSize(100, 100)
24 | self.click_cnt = 0
25 | # 시그널이 일어나면 self._pressed를 연결
26 | # pressed는 QPushButton의 부모위젯인 QAbstratButton에서 상속
27 | self.pressed.connect(self._pressed)
28 |
29 | @pyqtSlot() # pyqtSlot 데코레이터는 꼭 필요는 없다. 하지만 메모리 사용 및 호출 속도에서 약간의 이득을 얻을 수 있다.
30 | def _pressed(self):
31 | """
32 | 클릭 수를 카운터하여 표출
33 | """
34 | self.click_cnt += 1
35 | self.setText(str(self.click_cnt))
36 |
37 | if __name__ == "__main__":
38 | app = QApplication(sys.argv)
39 | form = Button()
40 | form.show()
41 | exit(app.exec_())
42 |
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/QLineEdit/QLineEdit_00_basic.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding: utf-8
3 |
4 | # 예제 내용
5 | # * QLineEdit 기본 사용
6 |
7 | import sys
8 |
9 | from PyQt5.QtWidgets import QWidget
10 | from PyQt5.QtWidgets import QBoxLayout
11 | from PyQt5.QtWidgets import QLabel
12 | from PyQt5.QtWidgets import QLineEdit
13 | from PyQt5.QtWidgets import QApplication
14 | from PyQt5.QtCore import Qt
15 |
16 |
17 | __author__ = "Deokyu Lim "
18 |
19 |
20 | class Form(QWidget):
21 | def __init__(self):
22 | QWidget.__init__(self, flags=Qt.Widget)
23 | self.init_widget()
24 |
25 | def init_widget(self):
26 | """
27 | 현재 위젯의 모양등을 초기화
28 | """
29 | self.setWindowTitle("QLineEdit Widget")
30 | form_lbx = QBoxLayout(QBoxLayout.TopToBottom, parent=self)
31 | self.setLayout(form_lbx)
32 |
33 | lb = QLabel()
34 | le = QLineEdit()
35 |
36 | le.textChanged.connect(lb.setText)
37 |
38 | form_lbx.addWidget(lb)
39 | form_lbx.addWidget(le)
40 |
41 | if __name__ == "__main__":
42 | app = QApplication(sys.argv)
43 | form = Form()
44 | form.show()
45 | exit(app.exec_())
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/QProgressBar/QProgressBar_00_basic.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding: utf-8
3 |
4 | # 예제 내용
5 | # * 실행상태바의 기본 사용
6 |
7 | import sys
8 |
9 | from PyQt5.QtWidgets import QWidget
10 | from PyQt5.QtWidgets import QProgressBar
11 | from PyQt5.QtWidgets import QScrollBar
12 | from PyQt5.QtWidgets import QApplication
13 | from PyQt5.QtWidgets import QBoxLayout
14 | from PyQt5.QtCore import Qt
15 |
16 | __author__ = "Deokyu Lim "
17 |
18 |
19 | class Form(QWidget):
20 | def __init__(self):
21 | QWidget.__init__(self, flags=Qt.Widget)
22 | self.init_widget()
23 |
24 | def init_widget(self):
25 | self.setWindowTitle("Hello World")
26 | form_lbx = QBoxLayout(QBoxLayout.TopToBottom, parent=self)
27 | self.setLayout(form_lbx)
28 |
29 | pgsb = QProgressBar()
30 | vscrb = QScrollBar(orientation=Qt.Horizontal)
31 | vscrb.setRange(0, 100)
32 | vscrb.valueChanged.connect(pgsb.setValue)
33 |
34 | form_lbx.addWidget(pgsb)
35 | form_lbx.addWidget(vscrb)
36 |
37 | if __name__ == "__main__":
38 | app = QApplication(sys.argv)
39 | form = Form()
40 | form.show()
41 | exit(app.exec_())
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/QWidget/QWidget_06_Change_Icon.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding: utf-8
3 |
4 | # 예제 내용
5 | # * 기본 위젯을 사용하여 기본 창을 생성
6 | # * '창 이름'을 변경한다.
7 |
8 | import sys
9 |
10 | from PyQt5.QtWidgets import QPushButton
11 | from PyQt5.QtWidgets import QApplication
12 | from PyQt5.QtGui import QIcon
13 |
14 | __author__ = "Deokyu Lim "
15 |
16 |
17 | class Form(QPushButton):
18 | def __init__(self):
19 | QPushButton.__init__(self)
20 | self.init_widget()
21 |
22 | def init_widget(self):
23 | """
24 | 현재 위젯의 모양등을 초기화
25 | """
26 | self.setWindowTitle("Hello World")
27 | self.setText("Change Icon")
28 | self.setCheckable(True)
29 | self.setChecked(False)
30 | self.change_window_icon(self.isChecked())
31 |
32 | self.clicked.connect(self.change_window_icon)
33 |
34 | def change_window_icon(self, v):
35 | icon = {True: "sword.png", False: 'shield.png'}
36 | app.setWindowIcon(QIcon(icon[v]))
37 | self.setIcon(QIcon(icon[v]))
38 |
39 |
40 |
41 |
42 | if __name__ == "__main__":
43 | app = QApplication(sys.argv)
44 | form = Form()
45 | form.show()
46 | exit(app.exec_())
47 |
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/QFileDialLog/QFileDialLog_00_basic.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding: utf-8
3 |
4 | # 예제 내용
5 | # * QTreeWidget을 사용하여 아이템을 표시
6 |
7 | __author__ = "Deokyu Lim "
8 |
9 | from PyQt5.QtWidgets import QWidget
10 | from PyQt5.QtWidgets import QFileDialog
11 | from PyQt5.QtWidgets import QPushButton
12 | from PyQt5.QtWidgets import QLabel
13 | from PyQt5.QtWidgets import QApplication
14 | from PyQt5.QtWidgets import QBoxLayout
15 | from PyQt5.QtCore import Qt
16 |
17 |
18 | class Form(QWidget):
19 | def __init__(self):
20 | QWidget.__init__(self, flags=Qt.Widget)
21 | self.setWindowTitle("QFileDialLog")
22 | box = QBoxLayout(QBoxLayout.TopToBottom)
23 | self.lb = QLabel()
24 | self.pb = QPushButton("Get full path of a file")
25 | box.addWidget(self.lb)
26 | box.addWidget(self.pb)
27 | self.setLayout(box)
28 | self.pb.clicked.connect(self.get_file_name)
29 |
30 | def get_file_name(self):
31 | filename = QFileDialog.getOpenFileName()
32 | self.lb.setText(filename[0])
33 |
34 |
35 | if __name__ == "__main__":
36 | import sys
37 | app = QApplication(sys.argv)
38 | form = Form()
39 | form.show()
40 | exit(app.exec_())
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/Buttons/Buttons_QCheckBox_00_basic.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding: utf-8
3 |
4 | # 예제 내용
5 | # * CheckBox 사용
6 |
7 | import sys
8 |
9 | from PyQt5.QtWidgets import QWidget
10 | from PyQt5.QtWidgets import QCheckBox
11 | from PyQt5.QtWidgets import QBoxLayout
12 |
13 | from PyQt5.QtWidgets import QApplication
14 | from PyQt5.QtCore import Qt
15 |
16 | __author__ = "Deokyu Lim "
17 |
18 |
19 | class Form(QWidget):
20 | def __init__(self):
21 | QWidget.__init__(self, flags=Qt.Widget)
22 | self.setWindowTitle("CheckBox")
23 |
24 | # 배치될 위젯 변수 선언
25 | cb_1 = QCheckBox("CheckBox 1")
26 | cb_2 = QCheckBox("CheckBox 2")
27 | cb_3 = QCheckBox("CheckBox 3")
28 | cb_4 = QCheckBox("CheckBox 4")
29 | cb_5 = QCheckBox("CheckBox 5")
30 |
31 | # 레이아웃 선언 및 Form Widget에 설정
32 | base_layout = QBoxLayout(QBoxLayout.TopToBottom, self)
33 | base_layout.addWidget(cb_1)
34 | base_layout.addWidget(cb_2)
35 | base_layout.addWidget(cb_3)
36 | base_layout.addWidget(cb_4)
37 | base_layout.addWidget(cb_5)
38 |
39 | self.setLayout(base_layout)
40 |
41 | if __name__ == "__main__":
42 | app = QApplication(sys.argv)
43 | form = Form()
44 | form.show()
45 | exit(app.exec_())
--------------------------------------------------------------------------------
/QtFramework/QtGui/QPixmap/QPixmap_05_crop.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding: utf-8
3 |
4 | # 예제 내용
5 | # * QPixmap사용
6 |
7 | import sys
8 | from PyQt5.QtWidgets import QWidget
9 | from PyQt5.QtWidgets import QLabel
10 | from PyQt5.QtWidgets import QBoxLayout
11 | from PyQt5.QtWidgets import QApplication
12 | from PyQt5.QtGui import QPixmap
13 | from PyQt5.QtCore import QRect
14 |
15 | __author__ = "Deokyu Lim "
16 |
17 |
18 | class Window(QWidget):
19 | def __init__(self):
20 | QWidget.__init__(self)
21 |
22 | self.init_ui()
23 |
24 | def init_ui(self):
25 | self.setMinimumWidth(320)
26 | self.setMinimumHeight(240)
27 | layout = QBoxLayout(QBoxLayout.LeftToRight)
28 | self.setLayout(layout)
29 |
30 | lb_1 = QLabel()
31 | pixmap = QPixmap("apple.jpg")
32 | pixmap = pixmap.scaledToHeight(240) # 사이즈가 조정
33 | lb_1.setPixmap(pixmap)
34 | layout.addWidget(lb_1)
35 |
36 | # 자를 영역 선택, 복사
37 | rect = QRect(50, 50, 50, 50)
38 | cropped = pixmap.copy(rect)
39 |
40 | lb_2 = QLabel()
41 | lb_2.setPixmap(cropped)
42 | layout.addWidget(lb_2)
43 |
44 |
45 | if __name__ == "__main__":
46 | app = QApplication(sys.argv)
47 | form = Window()
48 | form.show()
49 | exit(app.exec_())
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/Buttons/Buttons_QPushButton_03_Pressed_Released_event.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding: utf-8
3 |
4 | # 예제 내용
5 | # * 토클 버튼의 사용법을 알아본다
6 |
7 |
8 | import sys
9 |
10 | from PyQt5.QtWidgets import QPushButton
11 | from PyQt5.QtWidgets import QApplication
12 | from PyQt5.QtCore import pyqtSlot
13 |
14 | __author__ = "Deokyu Lim "
15 |
16 |
17 | class Button(QPushButton):
18 | def __init__(self):
19 | QPushButton.__init__(self, "Relesed")
20 | self.setFixedSize(100, 100)
21 | self.setStyleSheet("background-color: red")
22 |
23 | def mousePressEvent(self, QMouseEvent):
24 | self.setText("Pressing")
25 | self.setStyleSheet("background-color: green")
26 |
27 | def mouseReleaseEvent(self, QMouseEvent):
28 | self.setText("Relesed")
29 | self.setStyleSheet("background-color: red")
30 |
31 |
32 |
33 | @pyqtSlot(bool)
34 | def slot_toggle(self, state):
35 | """
36 | toggle 상태에 따라 배경색과 상태 텍스트 변환
37 | """
38 | self.setStyleSheet("background-color: %s" % ({True: "green", False: "red"}[state]))
39 | self.setText({True: "ON", False: "OFF"}[state])
40 |
41 | if __name__ == "__main__":
42 | app = QApplication(sys.argv)
43 | form = Button()
44 | form.show()
45 | exit(app.exec_())
46 |
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/QFileDialLog/QFileDialLog_01_initial_display.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding: utf-8
3 |
4 | # 예제 내용
5 | # * QTreeWidget을 사용하여 아이템을 표시
6 |
7 | __author__ = "Deokyu Lim "
8 |
9 | from PyQt5.QtWidgets import QWidget
10 | from PyQt5.QtWidgets import QFileDialog
11 | from PyQt5.QtWidgets import QPushButton
12 | from PyQt5.QtWidgets import QLabel
13 | from PyQt5.QtWidgets import QApplication
14 | from PyQt5.QtWidgets import QBoxLayout
15 | from PyQt5.QtCore import Qt
16 |
17 |
18 | class Form(QWidget):
19 | def __init__(self):
20 | QWidget.__init__(self, flags=Qt.Widget)
21 | self.setWindowTitle("QFileDialLog")
22 | box = QBoxLayout(QBoxLayout.TopToBottom)
23 | self.lb = QLabel()
24 | self.pb = QPushButton("Get full path of a file")
25 | box.addWidget(self.lb)
26 | box.addWidget(self.pb)
27 | self.setLayout(box)
28 | self.pb.clicked.connect(self.get_file_name)
29 |
30 | def get_file_name(self):
31 | filename = QFileDialog.getOpenFileName(
32 | caption="FILE DIALOG", directory=".", filter="*.py")
33 |
34 | self.lb.setText(filename[0])
35 |
36 |
37 | if __name__ == "__main__":
38 | import sys
39 | app = QApplication(sys.argv)
40 | form = Form()
41 | form.show()
42 | exit(app.exec_())
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/Buttons/Buttons_QRadioButton_00_basic.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding: utf-8
3 |
4 | # 예제 내용
5 | # * RadioButoon 배치
6 |
7 | import sys
8 |
9 | from PyQt5.QtWidgets import QWidget
10 | from PyQt5.QtWidgets import QRadioButton
11 | from PyQt5.QtWidgets import QBoxLayout
12 |
13 | from PyQt5.QtWidgets import QApplication
14 | from PyQt5.QtCore import Qt
15 |
16 | __author__ = "Deokyu Lim "
17 |
18 |
19 | class Form(QWidget):
20 | def __init__(self):
21 | QWidget.__init__(self, flags=Qt.Widget)
22 | self.setWindowTitle("RadioButton")
23 |
24 | # 배치될 위젯 변수 선언
25 | rb_1 = QRadioButton("RadioButton 1")
26 | rb_2 = QRadioButton("RadioButton 2")
27 | rb_3 = QRadioButton("RadioButton 3")
28 | rb_4 = QRadioButton("RadioButton 4")
29 | rb_5 = QRadioButton("RadioButton 5")
30 |
31 | # 레이아웃 선언 및 Form Widget에 설정
32 | base_layout = QBoxLayout(QBoxLayout.TopToBottom, self)
33 | base_layout.addWidget(rb_1)
34 | base_layout.addWidget(rb_2)
35 | base_layout.addWidget(rb_3)
36 | base_layout.addWidget(rb_4)
37 | base_layout.addWidget(rb_5)
38 |
39 | self.setLayout(base_layout)
40 |
41 | if __name__ == "__main__":
42 | app = QApplication(sys.argv)
43 | form = Form()
44 | form.show()
45 | exit(app.exec_())
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/QDockWidget/QDockWidget_00_basic.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding: utf-8
3 |
4 | # 예제 내용
5 | # * QDockWidget 사용
6 |
7 | import sys
8 | from PyQt5.QtWidgets import QMainWindow
9 | from PyQt5.QtWidgets import QDockWidget
10 | from PyQt5.QtWidgets import QTextEdit
11 | from PyQt5.QtWidgets import QApplication
12 | from PyQt5.QtCore import Qt
13 |
14 |
15 | __author__ = "Deokyu Lim "
16 |
17 |
18 | class Window(QMainWindow):
19 | def __init__(self):
20 | QMainWindow.__init__(self)
21 | self.dock_1 = QDockWidget(self)
22 | self.dock_2 = QDockWidget(self)
23 | self.init_window()
24 |
25 | def init_window(self):
26 | # 중앙 위젯
27 | self.setCentralWidget(QTextEdit())
28 |
29 | # Dock 설정
30 | self.dock_1.setWindowTitle("Dock1")
31 | # Dock이 붙을 수 있는 구역 설정
32 | self.dock_1.setAllowedAreas(
33 | Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea)
34 | # Dock의 처음 위치 설정
35 | self.addDockWidget(Qt.LeftDockWidgetArea, self.dock_1)
36 |
37 | self.dock_2.setWindowTitle("Dock2")
38 | self.dock_2.setAllowedAreas(Qt.RightDockWidgetArea)
39 | self.addDockWidget(Qt.RightDockWidgetArea, self.dock_2)
40 |
41 |
42 | if __name__ == "__main__":
43 | app = QApplication(sys.argv)
44 | form = Window()
45 | form.show()
46 | exit(app.exec_())
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/ItemWidget_Item_based/ItemWidget_QTreeWidget_00_basic.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding: utf-8
3 |
4 | # 예제 내용
5 | # * QTreeWidget을 사용하여 아이템을 표시
6 |
7 | __author__ = "Deokyu Lim "
8 |
9 | from PyQt5.QtWidgets import QWidget
10 | from PyQt5.QtWidgets import QTreeWidget
11 | from PyQt5.QtCore import QVariant
12 | from PyQt5.QtWidgets import QTreeWidgetItem
13 | from PyQt5.QtWidgets import QApplication
14 | from PyQt5.QtCore import Qt
15 |
16 |
17 | class Form(QWidget):
18 | def __init__(self):
19 | QWidget.__init__(self, flags=Qt.Widget)
20 | self.setWindowTitle("QTreeWidget")
21 | self.setFixedWidth(210)
22 | self.setFixedHeight(150)
23 |
24 | # QTreeView 생성 및 설정
25 | self.tw = QTreeWidget(self)
26 | self.tw.setColumnCount(2)
27 | self.tw.setHeaderLabels(["Type", "Name"])
28 | self.root = self.tw.invisibleRootItem()
29 |
30 | item = QTreeWidgetItem()
31 | item.setText(0, "Fruit")
32 | item.setText(1, "Apple")
33 | self.root.addChild(item)
34 |
35 | item = QTreeWidgetItem()
36 | item.setText(0, "Vegetable")
37 | item.setText(1, "Carrot")
38 | self.root.addChild(item)
39 |
40 |
41 | if __name__ == "__main__":
42 | import sys
43 | app = QApplication(sys.argv)
44 | form = Form()
45 | form.show()
46 | exit(app.exec_())
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/QComboBox/QComboBox_00_basic.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding: utf-8
3 |
4 | # 예제 내용
5 | # * QComboBox 기본 사용
6 |
7 | import sys
8 |
9 | from PyQt5.QtWidgets import QWidget
10 | from PyQt5.QtWidgets import QBoxLayout
11 | from PyQt5.QtWidgets import QLabel
12 | from PyQt5.QtWidgets import QComboBox
13 | from PyQt5.QtWidgets import QApplication
14 | from PyQt5.QtCore import Qt
15 | from PyQt5.QtCore import pyqtSlot
16 |
17 | __author__ = "Deokyu Lim "
18 |
19 |
20 | class Form(QWidget):
21 | def __init__(self):
22 | QWidget.__init__(self, flags=Qt.Widget)
23 | self.init_widget()
24 |
25 | def init_widget(self):
26 | """
27 | 현재 위젯의 모양등을 초기화
28 | """
29 | self.setWindowTitle("QComboBox Widget")
30 | form_lbx = QBoxLayout(QBoxLayout.TopToBottom, parent=self)
31 | self.setLayout(form_lbx)
32 |
33 | lb = QLabel()
34 |
35 | qb = QComboBox()
36 | qb.addItem("Banana") # 단일 아이템 추가시
37 | qb.addItems(["Apple", "Tomato", "Carrot"]) # 다수 아이템 추가시
38 | qb.insertSeparator(2) # 구분 선
39 | qb.currentTextChanged.connect(lb.setText) # 현재 인덱스의 데이터가 바뀔 때
40 |
41 | form_lbx.addWidget(qb)
42 | form_lbx.addWidget(lb)
43 |
44 | if __name__ == "__main__":
45 | app = QApplication(sys.argv)
46 | form = Form()
47 | form.show()
48 | exit(app.exec_())
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/Buttons/Buttons_QPushButton_04_shortcut.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding: utf-8
3 |
4 | # 예제 내용
5 | # * PushBottun에 단축키 부여
6 |
7 | import sys
8 |
9 | from PyQt5.QtWidgets import QWidget
10 | from PyQt5.QtWidgets import QPushButton
11 | from PyQt5.QtWidgets import QBoxLayout
12 |
13 | from PyQt5.QtWidgets import QApplication
14 | from PyQt5.QtCore import Qt
15 |
16 | __author__ = "Deokyu Lim "
17 |
18 |
19 | class Form(QWidget):
20 | def __init__(self):
21 | QWidget.__init__(self, flags=Qt.Widget)
22 | # 배치될 위젯 변수 선언
23 | self.pb_1 = QPushButton()
24 | self.pb_2 = QPushButton()
25 | # 레이아웃 선언 및 Form Widget에 설정
26 | self.layout_1 = QBoxLayout(QBoxLayout.TopToBottom, self)
27 | self.setLayout(self.layout_1)
28 | self.init_widget()
29 |
30 | def init_widget(self):
31 | self.setWindowTitle("PushButton Shortcut")
32 |
33 | # 라벨1의 설정 및 레이아웃 추가
34 | self.pb_1.setText("Alt + F7")
35 | self.pb_1.setShortcut("Alt+F7")
36 | self.layout_1.addWidget(self.pb_1)
37 |
38 | # 라벨2의 설정 및 레이아웃 추가
39 | self.pb_2.setText("Alt + F8")
40 | self.pb_2.setShortcut("Alt+F8")
41 | self.layout_1.addWidget(self.pb_2)
42 |
43 |
44 | if __name__ == "__main__":
45 | app = QApplication(sys.argv)
46 | form = Form()
47 | form.show()
48 | exit(app.exec_())
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/Signal_Slot/signal_slot_01_lambda.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding: utf-8
3 |
4 | # 예제 내용
5 | # * Signal Slot에서 lambda 함수 이용하기
6 |
7 | import sys
8 |
9 | from PyQt5.QtWidgets import QWidget
10 | from PyQt5.QtWidgets import QLabel
11 | from PyQt5.QtWidgets import QSlider
12 | from PyQt5.QtWidgets import QApplication
13 | from PyQt5.QtWidgets import QBoxLayout
14 | from PyQt5.QtCore import Qt
15 |
16 | __author__ = "Deokyu Lim "
17 |
18 |
19 | class Form(QWidget):
20 | def __init__(self):
21 | QWidget.__init__(self, flags=Qt.Widget)
22 | self.lb = QLabel()
23 | self.sd = QSlider(Qt.Horizontal)
24 | self.init_widget()
25 |
26 | def init_widget(self):
27 | self.setWindowTitle("Signal Slot")
28 | form_lbx = QBoxLayout(QBoxLayout.TopToBottom, parent=self)
29 | self.setLayout(form_lbx)
30 |
31 | # 시그널 슬롯 연결
32 | # QLabel.setText는 문자열만 받으므로 정수형을 주는 QSlider.valueChange를 바로 사용할 수 없다.
33 | # 이를 해결하기 위해선 따로 처리해주는 함수를 만들어 줘야하는데
34 | # lambda를 이용하여 값을 넘기는 방법을 사용하면 간편하게 해결할 수 있다.
35 | self.sd.valueChanged.connect(
36 | lambda v: self.lb.setText(str(v))
37 | )
38 |
39 | form_lbx.addWidget(self.lb)
40 | form_lbx.addWidget(self.sd)
41 |
42 | if __name__ == "__main__":
43 | app = QApplication(sys.argv)
44 | form = Form()
45 | form.show()
46 | exit(app.exec_())
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/QWizard/QWizard_01_is_completed.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding: utf-8
3 |
4 | # 예제 내용
5 | # QWizard 사용 예제
6 |
7 |
8 | import sys
9 |
10 | from PyQt5.QtWidgets import QWizard
11 | from PyQt5.QtWidgets import QWizardPage
12 | from PyQt5.QtWidgets import QBoxLayout
13 | from PyQt5.QtWidgets import QCheckBox
14 | from PyQt5.QtWidgets import QApplication
15 | from PyQt5.QtCore import Qt
16 |
17 | __author__ = "Deokyu Lim "
18 |
19 |
20 | class Start(QWizardPage):
21 | def __init__(self):
22 | QWizardPage.__init__(self)
23 | self.setTitle("Start Page")
24 | self.setSubTitle("Sub Start Page")
25 |
26 | layout = QBoxLayout(QBoxLayout.TopToBottom)
27 | self.setLayout(layout)
28 |
29 | self.checkbox = QCheckBox("Done")
30 | # 등록시 * 를 표시한 목록은 반드시 이벤트 후, 다음 페이지로 이동
31 | self.registerField("check*", self.checkbox)
32 | layout.addWidget(self.checkbox)
33 |
34 |
35 | class Form(QWizard):
36 | def __init__(self):
37 | QWizard.__init__(self, flags=Qt.Widget)
38 | self.init_widget()
39 | self.init_pages()
40 |
41 | def init_pages(self):
42 | self.addPage(Start())
43 |
44 | def init_widget(self):
45 | self.setWindowTitle("Hello World")
46 |
47 |
48 | if __name__ == "__main__":
49 | app = QApplication(sys.argv)
50 | form = Form()
51 | form.show()
52 | exit(app.exec_())
53 |
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/Signal_Slot/signal_slot_00_basic.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding: utf-8
3 |
4 | # 예제 내용
5 | # * Signal Slot의 기본 사용법
6 |
7 | import sys
8 |
9 | from PyQt5.QtWidgets import QWidget
10 | from PyQt5.QtWidgets import QDial
11 | from PyQt5.QtWidgets import QSlider
12 | from PyQt5.QtWidgets import QApplication
13 | from PyQt5.QtWidgets import QBoxLayout
14 | from PyQt5.QtCore import Qt
15 |
16 | __author__ = "Deokyu Lim "
17 |
18 |
19 | class Form(QWidget):
20 | def __init__(self):
21 | QWidget.__init__(self, flags=Qt.Widget)
22 | self.dl = QDial()
23 | self.sd = QSlider(Qt.Horizontal)
24 | self.init_widget()
25 |
26 | def init_widget(self):
27 | self.setWindowTitle("Signal Slot")
28 | form_lbx = QBoxLayout(QBoxLayout.TopToBottom, parent=self)
29 | self.setLayout(form_lbx)
30 |
31 | # 시그널 슬롯 연결
32 | # 다이얼의 값이 변하면 슬라이더의 값을 변경하는 슬롯과 연결
33 | # 슬라이더의 값이 변화하면 다이얼의 값을 변경하는 슬롯과 연결
34 | # 두 위젯의 valueChange 시그널은 현재값을 int형으로 반환
35 | # 두 위젯의 setValue 슬롯은 int형만을 받는다.
36 | self.dl.valueChanged.connect(self.sd.setValue)
37 | self.sd.valueChanged.connect(self.dl.setValue)
38 |
39 | form_lbx.addWidget(self.dl)
40 | form_lbx.addWidget(self.sd)
41 |
42 |
43 | if __name__ == "__main__":
44 | app = QApplication(sys.argv)
45 | form = Form()
46 | form.show()
47 | exit(app.exec_())
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/Signal_Slot/signal_slot_04_custom_slot.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding: utf-8
3 |
4 | # 예제 내용
5 | # * 사용자 정의 슬롯 생성 및 사용
6 |
7 | import sys
8 |
9 | from PyQt5.QtWidgets import QWidget
10 | from PyQt5.QtWidgets import QLabel
11 | from PyQt5.QtWidgets import QPushButton
12 | from PyQt5.QtWidgets import QApplication
13 | from PyQt5.QtWidgets import QBoxLayout
14 | from PyQt5.QtCore import Qt
15 | from PyQt5.QtCore import pyqtSlot
16 |
17 | __author__ = "Deokyu Lim "
18 |
19 |
20 | class Form(QWidget):
21 | def __init__(self):
22 | QWidget.__init__(self, flags=Qt.Widget)
23 | self.cnt = 0
24 | self.lb = QLabel(str(self.cnt))
25 | self.pb = QPushButton("Count")
26 |
27 | self.init_widget()
28 |
29 | def init_widget(self):
30 | self.setWindowTitle("Custom Signal")
31 | form_lbx = QBoxLayout(QBoxLayout.TopToBottom, parent=self)
32 | self.setLayout(form_lbx)
33 |
34 | # 시그널 슬롯 연결
35 | self.pb.clicked.connect(self.count)
36 |
37 | form_lbx.addWidget(self.lb)
38 | form_lbx.addWidget(self.pb)
39 |
40 | @pyqtSlot()
41 | def count(self):
42 | # pyqtSlot 데코레이터를 이용하여 메소드를 Qt Slot으로 명시해야한다.
43 | self.cnt += 1
44 | self.lb.setText(str(self.cnt))
45 |
46 | if __name__ == "__main__":
47 | app = QApplication(sys.argv)
48 | form = Form()
49 | form.show()
50 | exit(app.exec_())
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/QWidget/QWidget_stack_high_lower.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding: utf-8
3 |
4 | # 예제 내용
5 | # * 겹쳐진 위젯의 순서를 조정한다.
6 |
7 | import sys
8 |
9 | from PyQt5.QtWidgets import QWidget
10 | from PyQt5.QtWidgets import QLabel
11 | from PyQt5.QtWidgets import QApplication
12 | from PyQt5.QtCore import Qt
13 |
14 | __author__ = "Deokyu Lim "
15 |
16 |
17 | class StackWidget(QLabel):
18 | def __init__(self, color, parent=None):
19 | super(StackWidget, self).__init__(parent)
20 | self.setStyleSheet("background-color: %s" % color) # 라벨위젯과의 구분을 위한 색
21 |
22 | def mousePressEvent(self, event):
23 | """
24 | mouse가 위젯 위에서 클릭됐을때만 반응
25 | """
26 | if not self.underMouse():
27 | return
28 | self.raise_()
29 |
30 |
31 | class Form(QWidget):
32 | def __init__(self):
33 | QWidget.__init__(self, flags=Qt.Widget)
34 | self.setWindowTitle("Widget raise and lower")
35 |
36 | self.lb1 = StackWidget("red", parent=self)
37 | self.lb1.setGeometry(10, 10, 100, 100)
38 |
39 | self.lb2 = StackWidget("pink", parent=self)
40 | self.lb2.setGeometry(40, 40, 100, 100)
41 |
42 | self.lb3 = StackWidget("yellow", parent=self)
43 | self.lb3.setGeometry(70, 70, 100, 100)
44 |
45 | if __name__ == "__main__":
46 | app = QApplication(sys.argv)
47 | form = Form()
48 | form.show()
49 | exit(app.exec_())
50 |
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/QWebEngineView/QWebEngineView_08_alert.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding: utf-8
3 |
4 | # 예제 내용
5 | # * QWebEngineView 자바스크립트 경고창 커스터마이징
6 |
7 | import sys
8 | from PyQt5.QtWidgets import QApplication
9 | from PyQt5.QtCore import QDir
10 | from PyQt5.QtWebEngineWidgets import QWebEngineView
11 | from PyQt5.QtWebEngineWidgets import QWebEnginePage
12 | from PyQt5.QtCore import QUrl
13 | from PyQt5.QtWidgets import QMessageBox
14 |
15 | import qwebchannel_rc
16 |
17 | __author__ = "Deokyu Lim "
18 |
19 |
20 | class Page(QWebEnginePage):
21 | # 자바스크립트 경고 박스 요청시 호출
22 | def javaScriptAlert(self, url, msg):
23 | msg_box = QMessageBox(
24 | QMessageBox.Warning, "", "Error", QMessageBox.Ok)
25 | msg_box.setWindowTitle("Alert")
26 | msg_box.setInformativeText(msg)
27 | msg_box.exec()
28 | return
29 |
30 |
31 | class WebView(QWebEngineView):
32 | def __init__(self):
33 | QWebEngineView.__init__(self)
34 | # 사용자정의 Page 사용
35 | self.p = Page(self.page().profile())
36 | self.setPage(self.p)
37 | url = QDir().current().filePath(
38 | "html/QWebEngineView_08_alert.html")
39 | url = QUrl.fromLocalFile(url)
40 | self.page().setUrl(url)
41 |
42 |
43 | if __name__ == "__main__":
44 | sys.argv.append("--remote-debugging-port=8000")
45 |
46 | app = QApplication(sys.argv)
47 | form = WebView()
48 | form.show()
49 | exit(app.exec_())
50 |
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/QLineEdit/QLineEdit_02_completer.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding: utf-8
3 |
4 | # 예제 내용
5 | # * QLineEdit 기본 사용
6 |
7 | import sys
8 |
9 | from PyQt5.QtWidgets import QWidget
10 | from PyQt5.QtWidgets import QBoxLayout
11 | from PyQt5.QtWidgets import QLabel
12 | from PyQt5.QtWidgets import QLineEdit
13 | from PyQt5.QtWidgets import QApplication
14 | from PyQt5.QtWidgets import QCompleter
15 | from PyQt5.QtCore import QStringListModel
16 | from PyQt5.QtCore import Qt
17 |
18 | __author__ = "Deokyu Lim "
19 |
20 |
21 | class Form(QWidget):
22 | def __init__(self):
23 | QWidget.__init__(self, flags=Qt.Widget)
24 | self.init_widget()
25 |
26 | def init_widget(self):
27 | """
28 | 현재 위젯의 모양등을 초기화
29 | """
30 | self.setWindowTitle("QLineEdit Widget")
31 | form_lbx = QBoxLayout(QBoxLayout.TopToBottom, parent=self)
32 | self.setLayout(form_lbx)
33 |
34 | lb = QLabel()
35 | le = QLineEdit()
36 |
37 | model = QStringListModel()
38 | model.setStringList(["Hello", "Hi", "Bye", "Good", "Seoul"])
39 |
40 | completer = QCompleter()
41 | completer.setModel(model)
42 | le.setCompleter(completer)
43 |
44 | le.textChanged.connect(lb.setText)
45 |
46 | form_lbx.addWidget(lb)
47 | form_lbx.addWidget(le)
48 |
49 |
50 | if __name__ == "__main__":
51 | app = QApplication(sys.argv)
52 | form = Form()
53 | form.show()
54 | exit(app.exec_())
55 |
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/QToolBar/assets/icon_split_horizontal.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
46 |
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/QToolBar/assets/icon_split_vertical.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
46 |
--------------------------------------------------------------------------------
/QtFramework/QtGui/QPixmap/QPixmap_04_image_to_base64.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding: utf-8
3 |
4 | # 예제 내용
5 | # QPixmap을 Base64로 변환
6 |
7 | import sys
8 | from PyQt5.QtWidgets import QWidget
9 | from PyQt5.QtWidgets import QLabel
10 | from PyQt5.QtWidgets import QBoxLayout
11 | from PyQt5.QtWidgets import QTextEdit
12 | from PyQt5.QtWidgets import QApplication
13 |
14 | from PyQt5.QtGui import QPixmap
15 | from PyQt5.QtGui import QImage
16 | from PyQt5.QtCore import QByteArray
17 | from PyQt5.QtCore import QBuffer
18 |
19 |
20 | __author__ = "Deokyu Lim "
21 |
22 |
23 | class Window(QWidget):
24 | def __init__(self):
25 | QWidget.__init__(self)
26 |
27 | self.init_ui()
28 |
29 | def init_ui(self):
30 | self.setMinimumWidth(320)
31 | self.setMinimumHeight(240)
32 | lb = QLabel()
33 | te = QTextEdit()
34 | layout = QBoxLayout(QBoxLayout.LeftToRight)
35 | layout.addWidget(lb)
36 | layout.addWidget(te)
37 | self.setLayout(layout)
38 |
39 | # 사용할 그림 설정
40 | pixmap = QPixmap("apple.jpg")
41 | pixmap = pixmap.scaledToHeight(100) # 사이즈가 조정
42 | lb.setPixmap(pixmap)
43 |
44 | # PNG 포맷 및 Base64로 변환
45 | image: QImage = pixmap.toImage()
46 | data = QByteArray()
47 | buffer = QBuffer(data)
48 | image.save(buffer, 'PNG')
49 |
50 | te.setText(str(data.toBase64()))
51 |
52 |
53 |
54 |
55 |
56 | if __name__ == "__main__":
57 | app = QApplication(sys.argv)
58 | form = Window()
59 | form.show()
60 | exit(app.exec_())
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/QWidget/QWidget_opacity.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding: utf-8
3 |
4 | # 예제 내용
5 | # * 위젯의 투명도를 설정한다.
6 |
7 | import sys
8 |
9 | from PyQt5.QtWidgets import QWidget
10 | from PyQt5.QtWidgets import QApplication
11 | from PyQt5.QtCore import Qt
12 | from PyQt5.QtWidgets import QGraphicsOpacityEffect
13 |
14 | __author__ = "Deokyu Lim "
15 |
16 |
17 | class Form(QWidget):
18 | def __init__(self):
19 | QWidget.__init__(self, flags=Qt.Widget)
20 |
21 | # 투명도를 적용할 위젯
22 | self.w1 = QWidget(parent=self, flags=Qt.Widget)
23 | self.w3 = QWidget(parent=self, flags=Qt.Widget)
24 | self.w2 = QWidget(parent=self, flags=Qt.Widget)
25 |
26 | self.init_widget()
27 |
28 | def init_widget(self):
29 | self.setWindowTitle("Hello World")
30 |
31 | # 맨 아래 놓이게 될 위젯
32 | # 투명도를 설정하지 않음
33 | self.w1.setGeometry(10, 10, 100, 100)
34 | self.w1.setStyleSheet("background-color: yellow")
35 |
36 | # 중간에 놓이게 될 위젯
37 | # 투명도를 설정하지 않음
38 | self.w3.setGeometry(40, 40, 100, 100)
39 | self.w3.setStyleSheet("background-color: pink")
40 |
41 | # 가장 위에 놓이게 될 위젯
42 | self.w2.setGeometry(70, 70, 100, 100)
43 | opacity_effect = QGraphicsOpacityEffect(self.w2)
44 | opacity_effect.setOpacity(0.3)
45 | self.w2.setGraphicsEffect(opacity_effect)
46 | self.w2.setStyleSheet("background-color: red")
47 |
48 | if __name__ == "__main__":
49 | app = QApplication(sys.argv)
50 | form = Form()
51 | form.show()
52 | exit(app.exec_())
53 |
--------------------------------------------------------------------------------
/QtFramework/QtGui/QPixmap/QPixmap_02_render.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding: utf-8
3 |
4 | # 예제 내용
5 | # * QPixmap사용
6 |
7 | import sys
8 | from PyQt5.QtWidgets import QWidget
9 | from PyQt5.QtWidgets import QLabel
10 | from PyQt5.QtWidgets import QBoxLayout
11 | from PyQt5.QtWidgets import QPushButton
12 | from PyQt5.QtWidgets import QLineEdit
13 | from PyQt5.QtWidgets import QApplication
14 | from PyQt5.QtGui import QPixmap
15 | from PyQt5.QtCore import Qt
16 |
17 |
18 | __author__ = "Deokyu Lim "
19 |
20 |
21 | class Window(QWidget):
22 | def __init__(self):
23 | QWidget.__init__(self)
24 | self.lb_1 = QLabel()
25 | self.lb_2 = QLabel()
26 | self.le = QLineEdit()
27 | self.pb = QPushButton("Pixmap")
28 | self.init_ui()
29 |
30 | def init_ui(self):
31 | self.setMinimumWidth(320)
32 | self.setMinimumHeight(240)
33 | layout = QBoxLayout(QBoxLayout.TopToBottom)
34 | self.setLayout(layout)
35 |
36 | self.lb_1.setText("QPixmap Example")
37 |
38 | layout.addWidget(self.lb_1)
39 | layout.addWidget(self.lb_2)
40 | layout.addWidget(self.le)
41 | layout.addWidget(self.pb)
42 |
43 | self.le.textChanged.connect(self.lb_1.setText)
44 | self.pb.clicked.connect(self.save)
45 |
46 | def save(self):
47 | pixmap = QPixmap(self.lb_1.size())
48 | self.lb_1.render(pixmap)
49 | self.lb_2.setPixmap(pixmap)
50 |
51 | if __name__ == "__main__":
52 | app = QApplication(sys.argv)
53 | form = Window()
54 | form.show()
55 | exit(app.exec_())
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/ItemViews_model_based/ItemViews_QTreeView_03_style.css:
--------------------------------------------------------------------------------
1 | QTreeView {
2 | show-decoration-selected: 1;
3 | }
4 |
5 | QTreeView::item {
6 | color: darkgray;
7 | border: 1px solid #d9d9d9;
8 | border-top-color: transparent;
9 | border-bottom-color: transparent;
10 | }
11 |
12 | QTreeView::item:hover {
13 | background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #e7effd, stop: 1 #cbdaf1);
14 | border: 1px solid #bfcde4;
15 | }
16 |
17 | QTreeView::item:selected {
18 | border: 1px solid #567dbc;
19 | }
20 |
21 | QTreeView::item:selected:active{
22 | background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #6ea1f1, stop: 1 #567dbc);
23 | }
24 |
25 | QTreeView::item:selected:!active {
26 | background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1, stop: 0 #6b9be8, stop: 1 #577fbf);
27 | }
28 |
29 |
30 |
31 | QTreeView::branch {
32 | background: palette(base);
33 | }
34 |
35 | QTreeView::branch:has-siblings:!adjoins-item {
36 | background: cyan;
37 | }
38 |
39 | QTreeView::branch:has-siblings:adjoins-item {
40 | background: red;
41 | }
42 |
43 | QTreeView::branch:!has-children:!has-siblings:adjoins-item {
44 | background: blue;
45 | }
46 |
47 | QTreeView::branch:closed:has-children:has-siblings {
48 | background: pink;
49 | }
50 |
51 | QTreeView::branch:has-children:!has-siblings:closed {
52 | background: gray;
53 | }
54 |
55 | QTreeView::branch:open:has-children:has-siblings {
56 | background: magenta;
57 | }
58 |
59 | QTreeView::branch:open:has-children:!has-siblings {
60 | background: green;
61 | }
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/Buttons/Buttons_QCheckBox_01_change_state.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding: utf-8
3 |
4 | # 예제 내용
5 | # * CheckBox 사용
6 | # * CheckBox Signal 사용
7 |
8 | import sys
9 |
10 | from PyQt5.QtWidgets import QWidget
11 | from PyQt5.QtWidgets import QLabel
12 | from PyQt5.QtWidgets import QCheckBox
13 | from PyQt5.QtWidgets import QBoxLayout
14 |
15 | from PyQt5.QtWidgets import QApplication
16 | from PyQt5.QtCore import Qt
17 |
18 | from PyQt5.QtCore import pyqtSlot
19 |
20 | __author__ = "Deokyu Lim "
21 |
22 |
23 | class Form(QWidget):
24 | MSG = {True: "All Checked", False: "Not All Checked"}
25 |
26 | def __init__(self):
27 | QWidget.__init__(self, flags=Qt.Widget)
28 | self.setWindowTitle("CheckBox")
29 | base_layout = QBoxLayout(QBoxLayout.TopToBottom, self)
30 | self.setLayout(base_layout)
31 |
32 | # 배치될 위젯 변수 선언
33 | self.lb = QLabel()
34 | base_layout.addWidget(self.lb)
35 |
36 | # CheckBox 위젯 생성 및 시그널 연결
37 | self.cb_list = list()
38 | for i in range(2):
39 | w = QCheckBox("CheckBox %s" % i)
40 | w.stateChanged.connect(self._confirm)
41 | base_layout.addWidget(w)
42 | self.cb_list.append(w)
43 |
44 | # 현재 상태 라벨에 출력
45 | self._confirm()
46 |
47 | @pyqtSlot(int)
48 | def _confirm(self):
49 | state = all([bool(x.checkState()) for x in self.cb_list])
50 | self.lb.setText(self.MSG[state])
51 |
52 | if __name__ == "__main__":
53 | app = QApplication(sys.argv)
54 | form = Form()
55 | form.show()
56 | exit(app.exec_())
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/ItemWidget_Item_based/ItemWidget_QTreeWidget_00_basic_2.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding: utf-8
3 |
4 | # 예제 내용
5 | # * QTreeWidget을 사용하여 아이템을 표시
6 |
7 | __author__ = "Deokyu Lim "
8 |
9 | from PyQt5.QtWidgets import QWidget
10 | from PyQt5.QtWidgets import QTreeWidget
11 | from PyQt5.QtCore import QVariant
12 | from PyQt5.QtWidgets import QTreeWidgetItem
13 | from PyQt5.QtWidgets import QApplication
14 | from PyQt5.QtCore import Qt
15 |
16 |
17 | class Form(QWidget):
18 | def __init__(self):
19 | QWidget.__init__(self, flags=Qt.Widget)
20 | self.setWindowTitle("QTreeWidget")
21 | self.setFixedWidth(210)
22 | self.setFixedHeight(150)
23 |
24 | # QTreeView 생성 및 설정
25 | self.tw = QTreeWidget(self)
26 | self.tw.setColumnCount(2)
27 | self.tw.setHeaderLabels(["Type", "Color"])
28 | self.root = self.tw.invisibleRootItem()
29 |
30 | item = QTreeWidgetItem()
31 | item.setText(0, "Fruit")
32 | sub_item = QTreeWidgetItem()
33 | sub_item.setText(0, "Apple")
34 | sub_item.setText(1, "Red")
35 | item.addChild(sub_item)
36 | self.root.addChild(item)
37 |
38 | item = QTreeWidgetItem()
39 | item.setText(0, "Vegetable")
40 | sub_item = QTreeWidgetItem()
41 | sub_item.setText(0, "Corn")
42 | sub_item.setText(1, "Yellow")
43 | item.addChild(sub_item)
44 | self.root.addChild(item)
45 |
46 |
47 | if __name__ == "__main__":
48 | import sys
49 | app = QApplication(sys.argv)
50 | form = Form()
51 | form.show()
52 | exit(app.exec_())
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/QWidget/QWidget_enter_leave_evnet.py:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 |
3 | import sys
4 | from PyQt5.QtWidgets import QWidget
5 | from PyQt5.QtWidgets import QLabel
6 | from PyQt5.QtWidgets import QApplication
7 | from PyQt5.QtCore import Qt
8 |
9 |
10 | class IconWidget(QLabel):
11 | def __init__(self, parent=None):
12 | super(IconWidget, self).__init__(parent)
13 | color = "yellow"
14 | self.setStyleSheet("background-color: %s" % color) # 라벨위젯과의 구분을 위한 색
15 |
16 | def enterEvent(self, event):
17 | self.raise_()
18 |
19 | def leaveEvent(self, event):
20 | self.lower()
21 |
22 | class Dock(QWidget):
23 | def __init__(self, parent=None):
24 | super(Dock, self).__init__(parent, flags=Qt.Widget)
25 | self.default_interval = 10
26 | self.default_width = 100
27 | self.default_height = 100
28 | self.icons = []
29 |
30 | def _create_icon(self, n=10):
31 | self.icons = [IconWidget() for _ in range(n)]
32 |
33 |
34 | class Form(QWidget):
35 | def __init__(self):
36 | QWidget.__init__(self, flags=Qt.Widget)
37 | self.setWindowTitle("Widget raise and lower")
38 |
39 | self.lb1 = TestWidget("red", parent=self)
40 | self.lb1.setGeometry(10, 10, 100, 100)
41 |
42 | self.lb2 = TestWidget("pink", parent=self)
43 | self.lb2.setGeometry(40, 40, 100, 100)
44 |
45 | self.lb3 = TestWidget("yellow", parent=self)
46 | self.lb3.setGeometry(70, 70, 100, 100)
47 |
48 | if __name__ == "__main__":
49 | app = QApplication(sys.argv)
50 | form = Form()
51 | form.show()
52 | exit(app.exec_())
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/QWizard/QWizard_02_is_completed.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding: utf-8
3 |
4 | # 예제 내용
5 | # QWizard 사용 예제
6 |
7 |
8 | import sys
9 |
10 | from PyQt5.QtWidgets import QWizard
11 | from PyQt5.QtWidgets import QWizardPage
12 | from PyQt5.QtWidgets import QBoxLayout
13 | from PyQt5.QtWidgets import QSlider
14 | from PyQt5.QtWidgets import QApplication
15 | from PyQt5.QtCore import Qt
16 |
17 | __author__ = "Deokyu Lim "
18 |
19 |
20 | class Start(QWizardPage):
21 | def __init__(self):
22 | QWizardPage.__init__(self)
23 | self.setTitle("Start Page")
24 | self.setSubTitle("Sub Start Page")
25 |
26 | layout = QBoxLayout(QBoxLayout.TopToBottom)
27 | self.setLayout(layout)
28 |
29 | self.num = 0
30 | self.slider = QSlider()
31 | self.slider.valueChanged.connect(lambda v: setattr(self, "num", v))
32 |
33 | # 등록시 * 를 표시한 목록은 반드시 이벤트 후, 다음 페이지로 이동
34 | self.registerField("num*", self.slider)
35 | layout.addWidget(self.slider)
36 |
37 | def isComplete(self):
38 | print(self.num)
39 | if self.num != 99:
40 | return False
41 | return True
42 |
43 |
44 | class Form(QWizard):
45 | def __init__(self):
46 | QWizard.__init__(self, flags=Qt.Widget)
47 | self.page_start = Start()
48 | self.init_widget()
49 | self.init_pages()
50 |
51 | def init_pages(self):
52 | self.addPage(self.page_start)
53 |
54 | def init_widget(self):
55 | self.setWindowTitle("Hello World")
56 |
57 |
58 | if __name__ == "__main__":
59 | app = QApplication(sys.argv)
60 | form = Form()
61 | form.show()
62 | exit(app.exec_())
63 |
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/QWidget/QWidget_Find_Child_Widget.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding: utf-8
3 |
4 | # 예제 내용
5 | # * 위젯의 순서를 찾는 예제
6 |
7 | import sys
8 |
9 | from PyQt5.QtWidgets import QWidget
10 | from PyQt5.QtWidgets import QPushButton
11 | from PyQt5.QtWidgets import QLabel
12 | from PyQt5.QtWidgets import QApplication
13 | from PyQt5.QtCore import Qt
14 | from PyQt5.QtCore import qDebug
15 |
16 | __author__ = "Deokyu Lim "
17 |
18 |
19 | class Form(QWidget):
20 | def __init__(self):
21 | QWidget.__init__(self, flags=Qt.Widget)
22 |
23 | self.w1 = QWidget(self, Qt.Widget)
24 | self.w1.setObjectName("Object_1")
25 |
26 | self.w2 = QWidget(self, Qt.Widget)
27 | self.w3 = QWidget(self, Qt.Widget)
28 | self.w4 = QPushButton(self)
29 |
30 | self.w5 = QPushButton(self)
31 | self.w5.setObjectName("Object_1")
32 |
33 | self.w6 = QLabel()
34 | self.w6.setObjectName("Object_1")
35 |
36 | self.init_widget()
37 |
38 | def init_widget(self):
39 | self.setWindowTitle("Find Child Widget")
40 | templet = "{0:>50} : {1}"
41 | # 타입 매치
42 | w_list = self.findChildren(QWidget)
43 | qDebug(templet.format("type match", w_list))
44 |
45 | # 타입과 오브젝트 이름을 매치
46 | w_list = self.findChildren(QPushButton, "Object_1")
47 | qDebug(templet.format("type and object name match", w_list))
48 |
49 | w_list = self.findChildren((QPushButton, QLabel), "Object_1")
50 | qDebug(templet.format("tuple in types and object name match", w_list))
51 |
52 |
53 | if __name__ == "__main__":
54 | app = QApplication(sys.argv)
55 | form = Form()
56 | exit(app.exec_())
57 |
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/QLayout/QLayout_00_Basic.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding: utf-8
3 |
4 | # 예제 내용
5 | # * 기본 위젯을 사용하여 기본 창을 생성
6 | # * Layout 을 이용하여 위젯을 배치
7 |
8 | import sys
9 |
10 | from PyQt5.QtWidgets import QWidget
11 | from PyQt5.QtWidgets import QLabel
12 | from PyQt5.QtWidgets import QPushButton
13 | from PyQt5.QtWidgets import QBoxLayout
14 |
15 | from PyQt5.QtWidgets import QApplication
16 | from PyQt5.QtCore import Qt
17 |
18 | __author__ = "Deokyu Lim "
19 |
20 |
21 | class Form(QWidget):
22 | def __init__(self):
23 | QWidget.__init__(self, flags=Qt.Widget)
24 | # 배치될 위젯 변수 선언
25 | self.lb_1 = QLabel()
26 | self.lb_2 = QLabel()
27 | self.pb_1 = QPushButton()
28 | self.pb_2 = QPushButton()
29 | # 레이아웃 선언 및 Form Widget에 설정
30 | self.layout_1 = QBoxLayout(QBoxLayout.LeftToRight, self)
31 | self.setLayout(self.layout_1)
32 | self.init_widget()
33 |
34 | def init_widget(self):
35 | self.setWindowTitle("Layout Basic")
36 | self.setFixedWidth(640)
37 |
38 | # 라벨1의 설정 및 레이아웃 추가
39 | self.lb_1.setText("Label 1")
40 | self.lb_1.setStyleSheet("background-color: yellow")
41 | self.pb_1.setText("Button 1")
42 | self.layout_1.addWidget(self.lb_1)
43 | self.layout_1.addWidget(self.pb_1)
44 |
45 | # 라벨2의 설정 및 레이아웃 추가
46 | self.lb_2.setText("Label 2")
47 | self.lb_2.setStyleSheet("background-color: red")
48 | self.pb_2.setText("Button 2")
49 | self.layout_1.addWidget(self.lb_2)
50 | self.layout_1.addWidget(self.pb_2)
51 |
52 |
53 | if __name__ == "__main__":
54 | app = QApplication(sys.argv)
55 | form = Form()
56 | form.show()
57 | exit(app.exec_())
58 |
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/Buttons/Buttons_QRadioButton_01_buttons_in_group.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding: utf-8
3 |
4 | # 예제 내용
5 | # * RadioButoon 배치
6 |
7 | import sys
8 |
9 | from PyQt5.QtWidgets import QWidget
10 | from PyQt5.QtWidgets import QRadioButton
11 | from PyQt5.QtWidgets import QGroupBox
12 | from PyQt5.QtWidgets import QBoxLayout
13 |
14 | from PyQt5.QtWidgets import QApplication
15 | from PyQt5.QtCore import Qt
16 |
17 | __author__ = "Deokyu Lim "
18 |
19 |
20 | class Form(QWidget):
21 | def __init__(self):
22 | QWidget.__init__(self, flags=Qt.Widget)
23 | self.setWindowTitle("RadioButton")
24 |
25 | # 배치될 위젯 변수 선언
26 | grp_1 = QGroupBox("Group 1")
27 | grp_2 = QGroupBox("Group 2")
28 | rb_1 = QRadioButton("RadioButton 1")
29 | rb_2 = QRadioButton("RadioButton 2")
30 | rb_3 = QRadioButton("RadioButton 3")
31 | rb_4 = QRadioButton("RadioButton 4")
32 | rb_5 = QRadioButton("RadioButton 5")
33 |
34 | # 레이아웃 선언 및 Form Widget에 설정
35 | base_layout = QBoxLayout(QBoxLayout.TopToBottom, self)
36 | grp_1_layout = QBoxLayout(QBoxLayout.TopToBottom)
37 | grp_2_layout = QBoxLayout(QBoxLayout.TopToBottom)
38 |
39 | grp_1.setLayout(grp_1_layout)
40 | grp_2.setLayout(grp_2_layout)
41 |
42 | grp_1_layout.addWidget(rb_1)
43 | grp_1_layout.addWidget(rb_2)
44 | grp_1_layout.addWidget(rb_3)
45 | grp_2_layout.addWidget(rb_4)
46 | grp_2_layout.addWidget(rb_5)
47 |
48 | base_layout.addWidget(grp_1)
49 | base_layout.addWidget(grp_2)
50 |
51 | self.setLayout(base_layout)
52 |
53 | if __name__ == "__main__":
54 | app = QApplication(sys.argv)
55 | form = Form()
56 | form.show()
57 | exit(app.exec_())
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/QTabWidget/QTabWidget_01_add_tab.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding: utf-8
3 |
4 | # 예제 내용
5 | # * QTabWidget 탭에 다양한 위젯 추가
6 |
7 | import sys
8 |
9 | from PyQt5.QtWidgets import QWidget
10 | from PyQt5.QtWidgets import QBoxLayout
11 | from PyQt5.QtWidgets import QTextEdit
12 | from PyQt5.QtWidgets import QTabWidget
13 | from PyQt5.QtWidgets import QToolButton
14 | from PyQt5.QtWidgets import QApplication
15 | from PyQt5.QtCore import Qt
16 | from PyQt5.QtGui import QIcon
17 | from PyQt5.QtCore import pyqtSlot
18 |
19 | __author__ = "Deokyu Lim "
20 |
21 |
22 |
23 | class Form(QWidget):
24 | def __init__(self):
25 | QWidget.__init__(self, flags=Qt.Widget)
26 | self.tbw = QTabWidget()
27 | self.init_widget()
28 |
29 | def init_widget(self):
30 | """
31 | 현재 위젯의 모양등을 초기화
32 | """
33 | self.setWindowTitle("Tab Widget")
34 | form_lbx = QBoxLayout(QBoxLayout.TopToBottom, parent=self)
35 | self.setLayout(form_lbx)
36 |
37 | # 탭 추가 버튼 생성
38 | tbw_addbtn = QToolButton()
39 | self.tbw.setCornerWidget(tbw_addbtn, Qt.TopLeftCorner) # 버튼 위치
40 | tbw_addbtn.setAutoRaise(True) # 마우스가 올라오면 올라옴
41 | tbw_addbtn.setIcon(QIcon("plus_icon.png")) # 아이콘 지정
42 | tbw_addbtn.clicked.connect(self.add_new_tab) # 클릭시 시그널 지정
43 | form_lbx.addWidget(self.tbw)
44 |
45 | # 기본 탭 생성
46 | self.add_new_tab()
47 |
48 |
49 | @pyqtSlot()
50 | def add_new_tab(self):
51 | """
52 | 텍스트 에디트를 가진 텝을 생성
53 | """
54 | self.tbw.addTab(QTextEdit(), "tab #%d" % (self.tbw.count() + 1))
55 |
56 |
57 | if __name__ == "__main__":
58 | app = QApplication(sys.argv)
59 | form = Form()
60 | form.show()
61 | exit(app.exec_())
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/QTextEdit/QTextEdit_01_TextCursor.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding: utf-8
3 |
4 | # 예제 내용
5 | # * 기본 위젯을 사용하여 기본 창을 생성
6 | # * '창 이름'을 변경한다.
7 |
8 | import sys
9 |
10 | from PyQt5.QtWidgets import QWidget
11 | from PyQt5.QtWidgets import QTextEdit
12 | from PyQt5.QtWidgets import QApplication
13 | from PyQt5.QtWidgets import QBoxLayout
14 | from PyQt5.QtWidgets import QStatusBar
15 | from PyQt5.QtGui import QTextCursor
16 | from PyQt5.QtCore import Qt
17 | from PyQt5.QtCore import pyqtSlot
18 |
19 | __author__ = "Deokyu Lim "
20 |
21 | class StatusBar(QStatusBar):
22 | @pyqtSlot(QTextCursor)
23 | def change_cursor_info(self, data:QTextCursor):
24 | ss = data.selectionStart()
25 | se = data.selectionEnd()
26 |
27 | selected_info = ""
28 | if se - ss:
29 | selected_info = "{0} {1} ".format(se - ss, "char" if (se-ss) == 1 else "chars")
30 | self.showMessage("{0}{1}:{2}".format(
31 | selected_info,
32 | data.blockNumber(),
33 | data.columnNumber())
34 | )
35 |
36 |
37 | class Form(QWidget):
38 | def __init__(self):
39 | QWidget.__init__(self, flags=Qt.Widget)
40 | self.init_widget()
41 |
42 | def init_widget(self):
43 | self.setWindowTitle("Hello World")
44 | form_lbx = QBoxLayout(QBoxLayout.TopToBottom, parent=self)
45 | self.setLayout(form_lbx)
46 |
47 | te = QTextEdit()
48 | sb = StatusBar()
49 |
50 | form_lbx.addWidget(te)
51 | form_lbx.addWidget(sb)
52 |
53 | te.cursorPositionChanged.connect(lambda: sb.change_cursor_info(te.textCursor()))
54 |
55 | if __name__ == "__main__":
56 | app = QApplication(sys.argv)
57 | form = Form()
58 | form.show()
59 | exit(app.exec_())
60 |
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/Drag_and_Drop/drag_and_drop_00_basic.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | # 예제 내용
4 | # * 드래그 앤 드랍 사용
5 |
6 | import sys
7 |
8 | from PyQt5.QtWidgets import QWidget
9 | from PyQt5.QtWidgets import QPushButton
10 | from PyQt5.QtWidgets import QLineEdit
11 | from PyQt5.QtWidgets import QApplication
12 |
13 | from PyQt5.QtGui import QDragEnterEvent
14 | from PyQt5.QtGui import QDropEvent
15 | from PyQt5.QtCore import Qt
16 | from PyQt5.QtWidgets import QBoxLayout
17 |
18 | __author__ = "Deokyu Lim "
19 |
20 |
21 | class Button(QPushButton):
22 | def __init__(self, title):
23 | QPushButton.__init__(self, title)
24 | self.setAcceptDrops(True)
25 |
26 | def dragEnterEvent(self, e: QDragEnterEvent):
27 | """
28 | 여기서 event 진행의 허락을 결정해야 한다.
29 | """
30 | if e.mimeData().hasFormat('text/plain'):
31 | # mime타입이 text/plain 타입인지 검
32 | e.accept()
33 | else:
34 | e.ignore()
35 |
36 | def dropEvent(self, e: QDropEvent):
37 | self.setText(e.mimeData().text())
38 |
39 |
40 | class Form(QWidget):
41 | def __init__(self):
42 | QWidget.__init__(self, flags=Qt.Widget)
43 |
44 | self.init_widget()
45 |
46 | def init_widget(self):
47 | """
48 | 현재 위젯의 모양등을 초기화
49 | """
50 | self.setWindowTitle("Hello World")
51 | form_lbx = QBoxLayout(QBoxLayout.TopToBottom, self)
52 | self.setLayout(form_lbx)
53 |
54 | le = QLineEdit()
55 | le.setDragEnabled(True) # 드래그가 가능
56 |
57 | btn = Button("Button!")
58 | form_lbx.addWidget(le)
59 | form_lbx.addWidget(btn)
60 |
61 |
62 | if __name__ == "__main__":
63 | app = QApplication(sys.argv)
64 | form = Form()
65 | form.show()
66 | exit(app.exec_())
67 |
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/QSplitter/QSplitter_00_basic.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding: utf-8
3 |
4 | # 예제 내용
5 | # * 기본 위젯을 사용하여 기본 창을 생성
6 | # * '창 이름'을 변경한다.
7 |
8 | import sys
9 |
10 | from PyQt5.QtWidgets import QWidget
11 | from PyQt5.QtWidgets import QSplitter
12 | from PyQt5.QtWidgets import QTextEdit
13 | from PyQt5.QtWidgets import QVBoxLayout
14 |
15 | from PyQt5.QtWidgets import QApplication
16 | from PyQt5.QtCore import Qt
17 |
18 | __author__ = "Deokyu Lim "
19 |
20 |
21 | class Form(QWidget):
22 | """
23 | 만들고자 하는 프로그램의 기본이 되는 창 또는 폼 위젯.
24 | 본 위젯 위에 다른 위젯을 올려서 모양을 만든다.
25 |
26 | QWidget을 상속받아서 필요한 메소드를 작성.
27 | """
28 |
29 | def __init__(self):
30 | """
31 | 보통 __init__ (생성자)에서 필요한 것들을 다를 위젯들을 선언해줘도 되지만 init_widget을 따로 만들어서 호출한다.
32 | """
33 | QWidget.__init__(self, flags=Qt.Widget)
34 |
35 | self.te_1 = QTextEdit()
36 | self.te_2 = QTextEdit()
37 | self.te_3 = QTextEdit()
38 | self.split_1 = QSplitter()
39 | self.split_2 = QSplitter()
40 | self.vbox = QVBoxLayout()
41 | self.container_vbox = QVBoxLayout()
42 | self.init_widget()
43 |
44 | def init_widget(self):
45 | """
46 | 현재 위젯의 모양등을 초기화
47 | """
48 | self.setWindowTitle("Hello World")
49 | self.split_1.addWidget(self.te_1)
50 | self.split_1.addWidget(self.te_2)
51 | self.container_vbox.addWidget(self.split_1)
52 |
53 | self.split_2.setOrientation(Qt.Vertical)
54 | self.split_2.addWidget(self.split_1)
55 | self.split_2.addWidget(self.te_3)
56 |
57 |
58 | self.vbox.addWidget(self.split_2)
59 | self.setLayout(self.vbox)
60 |
61 | if __name__ == "__main__":
62 | app = QApplication(sys.argv)
63 | form = Form()
64 | form.show()
65 | exit(app.exec_())
66 |
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/QWidget/QWidget_08_mouse_tracker.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding: utf-8
3 |
4 | # 예제 내용
5 | # * 기본 위젯을 사용하여 기본 창을 생성
6 | # * '창 이름'을 변경한다.
7 |
8 | import sys
9 |
10 | from PyQt5.QtWidgets import QWidget
11 | from PyQt5.QtWidgets import QApplication
12 | from PyQt5.QtWidgets import QBoxLayout
13 | from PyQt5.QtWidgets import QLabel
14 | from PyQt5.QtCore import Qt
15 | from PyQt5.QtCore import QThread
16 | from PyQt5.QtGui import QCursor
17 | from PyQt5.QtCore import pyqtSignal
18 |
19 | __author__ = "Deokyu Lim "
20 |
21 |
22 | class MouseTracker(QThread):
23 | """
24 | 마우스의 위치를 쫓기 위한 Thread
25 | """
26 | # 마우스의 위치가가 변할 경우 발생
27 | changed_mouse_position = pyqtSignal(tuple)
28 |
29 | def run(self):
30 | cursor = None
31 | while True:
32 | c = QCursor.pos()
33 | # 마우스의 위치 변화가 없으면 넘어감
34 | if c != cursor:
35 | cursor = c
36 | self.changed_mouse_position.emit((cursor.x(), cursor.y()))
37 | self.usleep(1)
38 |
39 |
40 | class Form(QWidget):
41 | def __init__(self):
42 | QWidget.__init__(self, flags=Qt.Widget | Qt.FramelessWindowHint)
43 | self.init_widget()
44 |
45 | self.th = MouseTracker()
46 | self.th.changed_mouse_position.connect(
47 | lambda v:
48 | self.label.setText(
49 | "{}, {}".format(*v)))
50 | self.th.start()
51 |
52 | def init_widget(self):
53 | self.setWindowTitle("Hello World")
54 | self.setGeometry(10, 10, 100, 50)
55 | self.label = QLabel()
56 | layout = QBoxLayout(QBoxLayout.TopToBottom)
57 | layout.addWidget(self.label)
58 | self.setLayout(layout)
59 |
60 |
61 | if __name__ == "__main__":
62 | app = QApplication(sys.argv)
63 | form = Form()
64 | form.show()
65 | exit(app.exec_())
66 |
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/ItemWidget_Item_based/ItemWidget_QTreeWidget_01_column.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding: utf-8
3 |
4 | # 예제 내용
5 | # * QTreeWidget을 사용하여 아이템을 표시
6 |
7 | __author__ = "Deokyu Lim "
8 |
9 | from PyQt5.QtWidgets import QWidget
10 | from PyQt5.QtWidgets import QTreeWidget
11 | from PyQt5.QtCore import QVariant
12 | from PyQt5.QtWidgets import QTreeWidgetItem
13 | from PyQt5.QtWidgets import QApplication
14 | from PyQt5.QtCore import Qt
15 |
16 |
17 | class Form(QWidget):
18 | def __init__(self):
19 | QWidget.__init__(self, flags=Qt.Widget)
20 | self.setWindowTitle("QTreeWidget Column")
21 | self.setFixedWidth(210)
22 | self.setFixedHeight(150)
23 |
24 | # 데이터
25 | data = [
26 | {"type": "Fruit",
27 | "objects": [("Apple", "Red"), ("Banana", "Yellow")]},
28 | {"type": "Vegetable",
29 | "objects": [("Carrot", "Red"), ("Tomato", "Red")]},
30 | ]
31 | # QTreeView 생성 및 설정
32 | self.tw = QTreeWidget(self)
33 | self.tw.setColumnCount(2)
34 |
35 | for d in data:
36 | parent = self.add_tree_root(d['type'], "")
37 | for child in d['objects']:
38 | self.add_tree_child(parent, *child)
39 |
40 | def add_tree_root(self, name:str, description:str):
41 | item = QTreeWidgetItem(self.tw)
42 | item.setText(0, name)
43 | item.setText(1, description)
44 | return item
45 |
46 | def add_tree_child(self, parent:QTreeWidgetItem, name:str, description:str):
47 | item = QTreeWidgetItem()
48 | item.setText(0, name)
49 | item.setText(1, description)
50 | parent.addChild(item)
51 | return item
52 |
53 |
54 | if __name__ == "__main__":
55 | import sys
56 | app = QApplication(sys.argv)
57 | form = Form()
58 | form.show()
59 | exit(app.exec_())
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/QToolBar/QToolBar_00_basic.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding: utf-8
3 |
4 | # 예제 내용
5 | # QToolBar.
6 |
7 | import sys
8 | from PyQt5.QtWidgets import QMainWindow
9 | from PyQt5.QtWidgets import QTabWidget
10 | from PyQt5.QtWidgets import QStatusBar
11 | from PyQt5.QtWidgets import QAction
12 | from PyQt5.QtGui import QIcon
13 |
14 | from PyQt5.QtWidgets import QToolBar
15 | from PyQt5.QtWidgets import QLabel
16 | from PyQt5.QtWidgets import QApplication
17 | from PyQt5.QtCore import Qt
18 |
19 |
20 | __author__ = "Deokyu Lim "
21 |
22 |
23 | class Window(QMainWindow):
24 | def __init__(self):
25 | QMainWindow.__init__(self)
26 | self.init_window()
27 |
28 | def init_window(self):
29 | self.setMinimumWidth(320)
30 | self.setMinimumHeight(240)
31 | self.setTabPosition(Qt.RightDockWidgetArea, QTabWidget.North)
32 |
33 | # 중앙 위젯
34 | self.lb = QLabel()
35 | self.setCentralWidget(self.lb)
36 | self._init_toolbar()
37 |
38 | def _init_toolbar(self):
39 | self.toolbar = QToolBar(self)
40 | action_1 = QAction(self)
41 | action_1.setText("QAction_1")
42 | action_2 = QAction(self)
43 | action_2.setText("QAction_2")
44 | action_3 = QAction(self)
45 | action_3.setText("QAction_3")
46 | # triggered 는 시그널 처럼 사용할 수 있다.
47 | action_1.triggered.connect(lambda: self.lb.setText(action_1.text()))
48 | action_2.triggered.connect(lambda: self.lb.setText(action_2.text()))
49 | action_3.triggered.connect(lambda: self.lb.setText(action_3.text()))
50 | self.toolbar.addAction(action_1)
51 | self.toolbar.addAction(action_2)
52 | self.toolbar.addAction(action_3)
53 | self.addToolBar(self.toolbar)
54 |
55 | if __name__ == "__main__":
56 | app = QApplication(sys.argv)
57 | form = Window()
58 | form.show()
59 | exit(app.exec_())
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/GroupBox/QGroupBox_00_basic.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding: utf-8
3 |
4 | # 예제 내용
5 | # * QGroupBox에 위젯을 넣어 정렬
6 |
7 | import sys
8 |
9 | from PyQt5.QtWidgets import QWidget
10 | from PyQt5.QtWidgets import QGroupBox
11 | from PyQt5.QtWidgets import QCheckBox
12 | from PyQt5.QtWidgets import QRadioButton
13 | from PyQt5.QtWidgets import QBoxLayout
14 | from PyQt5.QtWidgets import QApplication
15 | from PyQt5.QtCore import Qt
16 |
17 | __author__ = "Deokyu Lim "
18 |
19 |
20 | class Form(QWidget):
21 | def __init__(self):
22 | QWidget.__init__(self, flags=Qt.Widget)
23 | self.init_widget()
24 |
25 | def init_widget(self):
26 | """
27 | 현재 위젯의 모양등을 초기화
28 | """
29 | self.setWindowTitle("Hello World")
30 | form_lbx = QBoxLayout(QBoxLayout.TopToBottom, parent=self)
31 | self.setLayout(form_lbx)
32 |
33 | # 1번 그룹박스 생성
34 | gb_1 = QGroupBox(self)
35 | gb_1.setTitle("GroupBox")
36 | form_lbx.addWidget(gb_1)
37 | lbx = QBoxLayout(QBoxLayout.LeftToRight, parent=self)
38 | gb_1.setLayout(lbx)
39 | lbx.addWidget(QCheckBox("check box #1"))
40 | lbx.addWidget(QCheckBox("check box #2"))
41 | lbx.addWidget(QCheckBox("check box #3"))
42 |
43 | # 2번 그룹박스, 사용여부 체크가 가능, 기본 값으로 사용안함
44 | gb_2 = QGroupBox(self)
45 | gb_2.setTitle("GroupBox")
46 | gb_2.setCheckable(True)
47 | gb_2.setChecked(False)
48 | form_lbx.addWidget(gb_2)
49 | lbx = QBoxLayout(QBoxLayout.LeftToRight, parent=self)
50 | gb_2.setLayout(lbx)
51 | lbx.addWidget(QRadioButton("radio button #1"))
52 | lbx.addWidget(QRadioButton("radio button #2"))
53 | lbx.addWidget(QRadioButton("radio button #3"))
54 |
55 |
56 | if __name__ == "__main__":
57 | app = QApplication(sys.argv)
58 | form = Form()
59 | form.show()
60 | exit(app.exec_())
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/ItemWidget_Item_based/ItemWidget_QListWidget_01_widget_item.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding: utf-8
3 |
4 | # 예제 내용
5 | # * QListWidget을 사용하여 아이템을 표시
6 |
7 | __author__ = "Deokyu Lim "
8 |
9 | from PyQt5.QtWidgets import QWidget
10 | from PyQt5.QtWidgets import QListWidgetItem
11 | from PyQt5.QtWidgets import QBoxLayout
12 | from PyQt5.QtCore import QVariant
13 | from PyQt5.QtWidgets import QListWidget
14 | from PyQt5.QtWidgets import QPushButton
15 | from PyQt5.QtWidgets import QApplication
16 | from PyQt5.QtCore import Qt
17 |
18 |
19 | class Item(QWidget):
20 | def __init__(self):
21 | QWidget.__init__(self, flags=Qt.Widget)
22 | layout = QBoxLayout(QBoxLayout.TopToBottom)
23 | pb = QPushButton("Hello")
24 | layout.addWidget(pb)
25 | layout.setSizeConstraint(QBoxLayout.SetFixedSize)
26 | self.setLayout(layout)
27 |
28 |
29 | class Form(QWidget):
30 | def __init__(self):
31 | QWidget.__init__(self, flags=Qt.Widget)
32 | self.setWindowTitle("QTreeWidget")
33 | layout = QBoxLayout(QBoxLayout.TopToBottom)
34 | self.viewer = QListWidget(self)
35 | layout.addWidget(self.viewer)
36 | self.setLayout(layout)
37 |
38 | item = QListWidgetItem(self.viewer)
39 | custom_widget = Item()
40 |
41 | # item은 custom_widget의 사이즈를 알지 못하므로 알려줘야 한다
42 | item.setSizeHint(custom_widget.sizeHint())
43 | self.viewer.setItemWidget(item, custom_widget)
44 | self.viewer.addItem(item)
45 |
46 | item = QListWidgetItem(self.viewer)
47 | custom_widget = Item()
48 | item.setSizeHint(custom_widget.sizeHint())
49 | self.viewer.setItemWidget(item, custom_widget)
50 | self.viewer.addItem(item)
51 |
52 |
53 |
54 | if __name__ == "__main__":
55 | import sys
56 | app = QApplication(sys.argv)
57 | form = Form()
58 | form.show()
59 | exit(app.exec_())
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/ItemWidget_Item_based/ItemWidget_QTreeWidget_02_header.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding: utf-8
3 |
4 | # 예제 내용
5 | # * QTreeWidget을 사용하여 아이템을 표시
6 |
7 | __author__ = "Deokyu Lim "
8 |
9 | from PyQt5.QtWidgets import QWidget
10 | from PyQt5.QtWidgets import QTreeWidget
11 | from PyQt5.QtCore import QVariant
12 | from PyQt5.QtWidgets import QTreeWidgetItem
13 | from PyQt5.QtWidgets import QApplication
14 | from PyQt5.QtCore import Qt
15 |
16 |
17 | class Form(QWidget):
18 | def __init__(self):
19 | QWidget.__init__(self, flags=Qt.Widget)
20 | self.setWindowTitle("QTreeWidget Column")
21 | self.setFixedWidth(210)
22 | self.setFixedHeight(150)
23 |
24 | # 데이터
25 | data = [
26 | {"type": "Fruit",
27 | "objects": [("Apple", "Red"), ("Banana", "Yellow")]},
28 | {"type": "Vegetable",
29 | "objects": [("Carrot", "Red"), ("Tomato", "Red")]},
30 | ]
31 | # QTreeView 생성 및 설정
32 | self.tw = QTreeWidget(self)
33 | self.tw.setColumnCount(2)
34 | self.tw.setHeaderLabels(["Type", "Color"])
35 |
36 | for d in data:
37 | parent = self.add_tree_root(d['type'], "")
38 | for child in d['objects']:
39 | self.add_tree_child(parent, *child)
40 |
41 | def add_tree_root(self, name:str, description:str):
42 | item = QTreeWidgetItem(self.tw)
43 | item.setText(0, name)
44 | item.setText(1, description)
45 | return item
46 |
47 | def add_tree_child(self, parent:QTreeWidgetItem, name:str, description:str):
48 | item = QTreeWidgetItem()
49 | item.setText(0, name)
50 | item.setText(1, description)
51 | parent.addChild(item)
52 | return item
53 |
54 |
55 | if __name__ == "__main__":
56 | import sys
57 | app = QApplication(sys.argv)
58 | form = Form()
59 | form.show()
60 | exit(app.exec_())
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/QWebEngineView/QWebEngineView_05_DownloadRequest.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding: utf-8
3 |
4 | # 예제 내용
5 | # * QWebEngineView 다운로드 요청
6 |
7 | import sys
8 |
9 | from PyQt5.QtCore import QDir
10 | from PyQt5.QtCore import QUrl
11 |
12 | from PyQt5.QtWebEngineWidgets import QWebEngineView
13 | from PyQt5.QtWebEngineWidgets import QWebEngineSettings
14 | from PyQt5.QtWebEngineWidgets import QWebEngineDownloadItem
15 |
16 | from PyQt5.QtWidgets import QApplication
17 | from PyQt5.QtWidgets import QFileDialog
18 |
19 |
20 | __author__ = "Deokyu Lim "
21 |
22 |
23 | class WebView(QWebEngineView):
24 | def __init__(self):
25 | QWebEngineView.__init__(self)
26 | self.settings().setAttribute(
27 | QWebEngineSettings.JavascriptCanOpenWindows, True)
28 |
29 | self.setPage(self.page())
30 | self.settings().setAttribute(QWebEngineSettings.JavascriptEnabled, True)
31 | self.settings().setAttribute(QWebEngineSettings.JavascriptCanOpenWindows, True)
32 | self.page().profile().downloadRequested.connect(self.download_file)
33 |
34 | # 로컬파일 사용시 절대경로만 사용해야 함
35 | url = QDir().current().filePath(
36 | "html/QWebEngineView_05_download_request.html")
37 | url = QUrl.fromLocalFile(url)
38 | self.setUrl(url)
39 |
40 | # 웹 다운로드 요청시 열어줄 파일 다이얼로그 처리
41 | def download_file(self, item: QWebEngineDownloadItem):
42 | # 다운로드 되는 것이 웹페이지 파일일 경우 포맷 지정
43 | # item.setSavePageFormat(QWebEngineDownloadItem.SingleHtmlSaveFormat)
44 | path = QFileDialog.getSaveFileName(self, "Save as", item.path())
45 | # 취소했다면 ('', '') 리턴
46 | if not path[0]:
47 | return
48 | # 다운받을 path 지정 및 다운로드 시작
49 | item.setPath(path[0])
50 | item.accept()
51 |
52 |
53 | if __name__ == "__main__":
54 | app = QApplication(sys.argv)
55 | form = WebView()
56 | form.show()
57 | exit(app.exec_())
58 |
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/QComboBox/QComboBox_01_model.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding: utf-8
3 |
4 | # 예제 내용
5 | # * QComboBox 기본 사용
6 |
7 | import sys
8 |
9 | from PyQt5.QtWidgets import QWidget
10 | from PyQt5.QtWidgets import QBoxLayout
11 | from PyQt5.QtWidgets import QLabel
12 | from PyQt5.QtWidgets import QComboBox
13 | from PyQt5.QtWidgets import QApplication
14 | from PyQt5.QtCore import Qt
15 | from PyQt5.QtCore import QVariant
16 | from PyQt5.QtGui import QStandardItemModel
17 | from PyQt5.QtGui import QStandardItem
18 |
19 | __author__ = "Deokyu Lim "
20 |
21 |
22 | class UserModel(QStandardItemModel):
23 | def __init__(self, data=None, parent=None):
24 | QStandardItemModel.__init__(self, parent)
25 | for i, d in enumerate(data):
26 | self.setItem(i, 0, QStandardItem(d))
27 |
28 | def data(self, QModelIndex, role=None):
29 | data = self.itemData(QModelIndex)
30 | if role == Qt.DisplayRole:
31 | return "%s" % (data[role])
32 | elif role == Qt.UserRole:
33 | print(data[role])
34 | return QVariant()
35 |
36 |
37 | class Form(QWidget):
38 | def __init__(self):
39 | QWidget.__init__(self, flags=Qt.Widget)
40 | self.init_widget()
41 |
42 | def init_widget(self):
43 | """
44 | 현재 위젯의 모양등을 초기화
45 | """
46 | self.setWindowTitle("QComboBox Widget")
47 | form_lbx = QBoxLayout(QBoxLayout.TopToBottom, parent=self)
48 | self.setLayout(form_lbx)
49 |
50 | data = ["Apple", "Banana"]
51 | model = UserModel(data)
52 |
53 | lb = QLabel()
54 |
55 | qb = QComboBox()
56 | qb.setModel(model)
57 | qb.currentTextChanged.connect(lb.setText) # 현재 인덱스의 데이터가 바뀔 때
58 |
59 | form_lbx.addWidget(qb)
60 | form_lbx.addWidget(lb)
61 |
62 | if __name__ == "__main__":
63 | app = QApplication(sys.argv)
64 | form = Form()
65 | form.show()
66 | exit(app.exec_())
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/Signal_Slot/signal_slot_02_custom_signal.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding: utf-8
3 |
4 | # 예제 내용
5 | # * 사용자정의 시그널 만들어 사용하기
6 |
7 | import sys
8 |
9 | from PyQt5.QtWidgets import QWidget
10 | from PyQt5.QtWidgets import QTextEdit
11 | from PyQt5.QtWidgets import QApplication
12 | from PyQt5.QtWidgets import QBoxLayout
13 | from PyQt5.QtCore import Qt
14 | from PyQt5.QtCore import QThread
15 | from PyQt5.QtCore import pyqtSignal
16 |
17 | import time
18 | __author__ = "Deokyu Lim "
19 |
20 |
21 | class TicGenerator(QThread):
22 | """
23 | 5초마다 틱 신호를 전달
24 | """
25 | # 사용자 정의 시그널 선언
26 | # 외부에서 사용할때 tic대신 Tic을 이용하여 호출할 수 있다.
27 | # Qt의 시그널 및 슬롯 이름은 Camel을 사용하기 때문에 파이썬의 PEP8을 지키면서 작성한다면 name을 반드시 사용
28 | tic = pyqtSignal(name="Tic")
29 |
30 | def __init__(self):
31 | QThread.__init__(self)
32 |
33 | def __del__(self):
34 | self.wait()
35 |
36 | def run(self):
37 | while True:
38 | t = int(time.time())
39 | if not t % 5 == 0:
40 | self.usleep(1)
41 | continue
42 | self.Tic.emit()
43 | self.msleep(1000)
44 |
45 |
46 | class Form(QWidget):
47 | def __init__(self):
48 | QWidget.__init__(self, flags=Qt.Widget)
49 | self.te = QTextEdit()
50 | self.tic_gen = TicGenerator()
51 | self.init_widget()
52 | self.tic_gen.start()
53 |
54 | def init_widget(self):
55 | self.setWindowTitle("Custom Signal")
56 | form_lbx = QBoxLayout(QBoxLayout.TopToBottom, parent=self)
57 | self.setLayout(form_lbx)
58 |
59 | # 시그널 슬롯 연결
60 | self.tic_gen.Tic.connect(
61 | lambda: self.te.insertPlainText(time.strftime("[%H:%M:%S] Tic!\n"))
62 | )
63 |
64 | form_lbx.addWidget(self.te)
65 |
66 |
67 |
68 | if __name__ == "__main__":
69 | app = QApplication(sys.argv)
70 | form = Form()
71 | form.show()
72 | exit(app.exec_())
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/QWidget/QWidget_01_Properties.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding: utf-8
3 |
4 | # 예제 내용
5 | # * Label을 Form에 붙여서 텍스트 출력
6 | # * QWidget이 가진 속성을 출력
7 |
8 | import sys
9 |
10 | from PyQt5.QtWidgets import QWidget
11 | from PyQt5.QtWidgets import QLabel
12 | from PyQt5.QtWidgets import QApplication
13 | from PyQt5.QtCore import Qt
14 |
15 | __author__ = "Deokyu Lim "
16 |
17 |
18 | class Form(QWidget):
19 | def __init__(self):
20 | QWidget.__init__(self, flags=Qt.Widget)
21 |
22 | # self 변수 초기화. 꼭 필요하지는 않음
23 | self.lb = None
24 |
25 | self.init_widget()
26 |
27 | def init_widget(self):
28 | self.setWindowTitle("Hello World")
29 | self.setGeometry(100, 100, 640, 480) # 창 위치, 크기 설정
30 |
31 | # QLabel 인스턴스 생성
32 | # 인자값으로 parent인 self 지정
33 | # QLabel(str, parent), QLabel(parent) 등으로 줄 수 있음
34 | self.lb = QLabel(self)
35 | properties_list = (
36 | "width", "height", "x", "y", "geometry",
37 | "maximumHeight", "maximumWidth", "maximumSize", "minimumSize", "minimumWidth",
38 | "size", "windowFilePath", "windowTitle"
39 | ) # 출력할 property 이름
40 | msg = self.get_properties_value(properties_list) # property 이름과 값을 돌려주는 함수 호출
41 | self.lb.setText(msg) # Label에 텍스트 설정
42 |
43 | def get_properties_value(self, properties):
44 | """
45 | 인자 값으로 property의 이름을 담은 시퀀스 자료형
46 | property를 차례로 호출하며 이름과 값의 문자열 생성
47 |
48 | :param properties list or tuple
49 | :return str
50 | """
51 | msg = []
52 | for p in properties:
53 | if not hasattr(self, p):
54 | continue
55 | value = getattr(self, p)() # == self.width(), self.x()
56 | msg.append("{:>20s} : {:<30s}".format(p, str(value)))
57 | msg = "\n".join(msg)
58 | return msg
59 |
60 |
61 | if __name__ == "__main__":
62 | app = QApplication(sys.argv)
63 | form = Form()
64 | form.show()
65 | exit(app.exec_())
66 |
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/Drag_and_Drop/drag_and_drop_01_move_button.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | # 예제 내용
4 | # * 드래그 앤 드랍 사용
5 |
6 | import sys
7 |
8 | from PyQt5.QtWidgets import QWidget
9 | from PyQt5.QtWidgets import QPushButton
10 | from PyQt5.QtWidgets import QApplication
11 |
12 | from PyQt5.QtGui import QDragEnterEvent
13 | from PyQt5.QtGui import QDropEvent
14 | from PyQt5.QtGui import QMouseEvent
15 | from PyQt5.QtGui import QDrag
16 | from PyQt5.QtGui import QPixmap
17 |
18 | from PyQt5.QtCore import Qt
19 | from PyQt5.QtCore import QMimeData
20 |
21 |
22 | __author__ = "Deokyu Lim "
23 |
24 |
25 | class Button(QPushButton):
26 | def __init__(self, title, parent):
27 | QPushButton.__init__(self, title, parent)
28 | self.offset = 0
29 |
30 | def mouseMoveEvent(self, e: QMouseEvent):
31 | # 왼쪽 버튼은 클릭용이므로 오른쪽 버튼 입력 허용
32 | if e.buttons() != Qt.RightButton:
33 | return
34 |
35 | mime_data = QMimeData() # 데이터 전송을 위한 MIME 객체 선언
36 | drag = QDrag(self) # QDrag는 오직 드래그앤드랍에서만 사용
37 | drag.setMimeData(mime_data)
38 |
39 | drag.exec_(Qt.MoveAction)
40 |
41 |
42 | class Form(QWidget):
43 | def __init__(self):
44 | QWidget.__init__(self, flags=Qt.Widget)
45 | self.setFixedSize(300, 300)
46 | self.btn = Button("Drag me to the moon", self)
47 | self.init_widget()
48 |
49 | def init_widget(self):
50 | """
51 | 현재 위젯의 모양등을 초기화
52 | """
53 | self.setWindowTitle("Drag and Drop")
54 | self.setAcceptDrops(True)
55 | self.btn.show()
56 |
57 | def dragEnterEvent(self, e: QDragEnterEvent):
58 | # 들어오는 이벤트들 모두 통과
59 | e.accept()
60 |
61 | def dropEvent(self, e: QDropEvent):
62 | # 마우스 위치를 이용하여 버튼의 위치를 변경
63 | position = e.pos()
64 | self.btn.move(position)
65 |
66 | e.setDropAction(Qt.MoveAction)
67 | e.accept()
68 |
69 |
70 | if __name__ == "__main__":
71 | app = QApplication(sys.argv)
72 | form = Form()
73 | form.show()
74 | exit(app.exec_())
75 |
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/QLayout/QLayout_01_Basic.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding: utf-8
3 |
4 | # 예제 내용
5 | # * 기본 위젯을 사용하여 기본 창을 생성
6 | # * Layout 을 이용하여 위젯을 배치
7 | # * Layout 배치시 정렬 설정
8 |
9 | import sys
10 |
11 | from PyQt5.QtWidgets import QWidget
12 | from PyQt5.QtWidgets import QLabel
13 | from PyQt5.QtWidgets import QBoxLayout
14 |
15 | from PyQt5.QtWidgets import QApplication
16 | from PyQt5.QtCore import Qt
17 |
18 | __author__ = "Deokyu Lim "
19 |
20 |
21 | class Form(QWidget):
22 | def __init__(self):
23 | QWidget.__init__(self, flags=Qt.Widget)
24 |
25 | # 배치될 위젯 변수 선언
26 | self.lb_1 = QLabel()
27 | self.lb_2 = QLabel()
28 | self.lb_3 = QLabel()
29 | self.lb_4 = QLabel()
30 | self.lb_5 = QLabel()
31 |
32 | # 레이아웃 선언 및 Form Widget에 설정
33 | self.layout_1 = QBoxLayout(QBoxLayout.LeftToRight, self)
34 | self.setLayout(self.layout_1)
35 | self.init_widget()
36 |
37 | def init_widget(self):
38 | self.setWindowTitle("Layout Basic")
39 | self.setFixedWidth(640)
40 | self.setFixedHeight(480)
41 |
42 | self.lb_1.setText("Label 1")
43 | self.lb_2.setText("Label 2")
44 | self.lb_3.setText("Label 3")
45 | self.lb_4.setText("Label 4")
46 | self.lb_5.setText("Label 5")
47 |
48 | self.lb_1.setStyleSheet("background-color: yellow")
49 | self.lb_2.setStyleSheet("background-color: red")
50 | self.lb_3.setStyleSheet("background-color: blue")
51 | self.lb_4.setStyleSheet("background-color: pink")
52 | self.lb_5.setStyleSheet("background-color: grey")
53 |
54 | self.layout_1.addWidget(self.lb_1)
55 | self.layout_1.addWidget(self.lb_2, alignment=Qt.AlignTop)
56 | self.layout_1.addWidget(self.lb_3, alignment=Qt.AlignBottom)
57 | self.layout_1.addWidget(self.lb_4, alignment=Qt.AlignVCenter)
58 | self.layout_1.addWidget(self.lb_5, alignment=Qt.AlignHCenter)
59 |
60 |
61 | if __name__ == "__main__":
62 | app = QApplication(sys.argv)
63 | form = Form()
64 | form.show()
65 | exit(app.exec_())
66 |
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/ItemViews_model_based/ItemViews_QListView_01_user_list_model.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding: utf-8
3 |
4 | # 예제 내용
5 | # * QListView 기본 사용법
6 | # * QAbstractListModel 을 이용한 사용자 모델 생성
7 |
8 | import sys
9 |
10 | from PyQt5.QtWidgets import QWidget
11 | from PyQt5.QtWidgets import QListView
12 | from PyQt5.QtCore import QAbstractListModel
13 | from PyQt5.QtCore import QVariant
14 | from PyQt5.QtGui import QBrush
15 | from PyQt5.QtGui import QColor
16 | from PyQt5.QtWidgets import QApplication
17 | from PyQt5.QtCore import Qt
18 |
19 | __author__ = "Deokyu Lim "
20 |
21 |
22 | class UserModel(QAbstractListModel):
23 | def __init__(self, data=None, parent=None):
24 | QAbstractListModel.__init__(self, parent)
25 | self._data = data
26 |
27 | def rowCount(self, parent=None, *args, **kwargs):
28 | return len(self._data)
29 |
30 | def data(self, QModelIndex, role=None):
31 | item = self._data[QModelIndex.row()]
32 |
33 | if role == Qt.DisplayRole:
34 | return "%s" % (item['name'])
35 | elif role == Qt.DecorationRole:
36 | return QColor(item['color'])
37 | elif role == Qt.BackgroundRole:
38 | return QBrush(Qt.Dense7Pattern)
39 | elif role == Qt.ToolTipRole:
40 | return "Tool Tip: %s" % (item['name'])
41 | return QVariant()
42 |
43 |
44 | class Form(QWidget):
45 | def __init__(self):
46 | QWidget.__init__(self, flags=Qt.Widget)
47 | self.setWindowTitle("ItemView QListView")
48 | self.setFixedWidth(210)
49 | self.setFixedHeight(100)
50 |
51 | fruits = [
52 | {"name": "banana", "color": "yellow", "bg_color": "yellow"},
53 | {"name": "apple", "color": "red", "bg_color": "red"},
54 | {"name": "pear", "color": "green", "bg_color": "gray"},
55 | ]
56 |
57 | view = QListView(self)
58 | model = UserModel(fruits)
59 | view.setModel(model)
60 |
61 |
62 | if __name__ == "__main__":
63 | app = QApplication(sys.argv)
64 | form = Form()
65 | form.show()
66 | exit(app.exec_())
67 |
--------------------------------------------------------------------------------
/QtFramework/Qt/Internationalization/i18n_02/i18n_02.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding: utf-8
3 |
4 | # 예제 내용
5 | # i18n 을 위한 예제
6 | # 창의 기본 이름이 Hello World지만 한국어 사용일 경우 안녕 세계가 뜨로록 한다.
7 | # * '창 이름'을 변경한다.
8 |
9 | import sys
10 |
11 | from PyQt5.QtWidgets import QWidget
12 | from PyQt5.QtWidgets import QApplication
13 | from PyQt5.QtCore import QTranslator
14 | from PyQt5.QtCore import Qt
15 | from PyQt5.QtCore import QEvent
16 | from PyQt5.QtCore import QLocale
17 |
18 | from PyQt5.QtWidgets import QLabel
19 | from PyQt5.QtWidgets import QComboBox
20 | from PyQt5.QtWidgets import QBoxLayout
21 |
22 | from PyQt5.QtCore import pyqtSlot
23 |
24 | __author__ = "Deokyu Lim "
25 |
26 |
27 | class Form(QWidget):
28 | I18N = [
29 | ["English", "translate\en_US.qm"],
30 | ["한국어", "translate\ko_KR.qm"],
31 | ["日本語", "translate\ja_JP.qm"]
32 | ]
33 | def __init__(self):
34 | QWidget.__init__(self, flags=Qt.Window)
35 | self.setMinimumWidth(330)
36 | self.lb = QLabel()
37 | self.qb = QComboBox()
38 | self.qb.addItems([n[0] for n in self.I18N]) # 콤보 박스에 지원하는 언어 삽입
39 | self.init_widget()
40 |
41 | def init_widget(self):
42 | self.setWindowTitle("{} - {}".format(self.tr("Hello World"), self.tr("English")))
43 |
44 | form_lbx = QBoxLayout(QBoxLayout.TopToBottom, parent=self)
45 | self.setLayout(form_lbx)
46 |
47 | self.lb.setText(self.tr("Good Morning"))
48 | self.lb.setStyleSheet("font-size: 30px")
49 | self.qb.currentIndexChanged.connect(self.change_locale) # 콤보박스의 선택된 내용이 바뀌면 시그널
50 |
51 | form_lbx.addWidget(self.qb)
52 | form_lbx.addWidget(self.lb)
53 |
54 | @pyqtSlot(int)
55 | def change_locale(self, idx):
56 | global translator
57 | global app
58 |
59 | # 번역스크립트 교체
60 | app.removeTranslator(translator)
61 | t = self.I18N[idx][1]
62 | translator.load(t)
63 | app.installTranslator(translator)
64 | self.init_widget()
65 |
66 |
67 | if __name__ == "__main__":
68 | app = QApplication(sys.argv)
69 |
70 | # 다국어 지원
71 | translator = QTranslator()
72 | translator.load("translate\en_US.qm")
73 | app.installTranslator(translator)
74 |
75 | form = Form()
76 | form.show()
77 |
78 | exit(app.exec_())
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/Signal_Slot/signal_slot_05_custom_slot.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding: utf-8
3 |
4 | # 예제 내용
5 | # * 사용자 정의 슬롯이 다양한 타입의 값을 받을 수 있게 만들기
6 |
7 | import sys
8 |
9 | from PyQt5.QtWidgets import QWidget
10 | from PyQt5.QtWidgets import QDial
11 | from PyQt5.QtWidgets import QSlider
12 | from PyQt5.QtWidgets import QLineEdit
13 | from PyQt5.QtWidgets import QApplication
14 | from PyQt5.QtWidgets import QBoxLayout
15 | from PyQt5.QtCore import Qt
16 | from PyQt5.QtCore import pyqtSlot
17 |
18 | __author__ = "Deokyu Lim "
19 |
20 |
21 | class CustomSlider(QSlider):
22 | def __init__(self, *args):
23 | QSlider.__init__(self, *args)
24 |
25 | @pyqtSlot(int)
26 | @pyqtSlot(str)
27 | def setValue(self, value):
28 | # int형과 str형을 받을 수 있도록 데코레이터를 쌓아두었다.
29 | value = int(value) # 숫자 이외의 값이 들어오면 여기서 죽게된다.
30 | QSlider.setValue(self, value)
31 |
32 |
33 | class Form(QWidget):
34 | def __init__(self):
35 | QWidget.__init__(self, flags=Qt.Widget)
36 | self.cnt = 0
37 | self.le = QLineEdit()
38 | self.dial = QDial()
39 | self.sld = CustomSlider(Qt.Horizontal)
40 |
41 | self.init_widget()
42 |
43 | def init_widget(self):
44 | self.setWindowTitle("Custom Slot")
45 | form_lbx = QBoxLayout(QBoxLayout.TopToBottom, parent=self)
46 | control_lbx = QBoxLayout(QBoxLayout.LeftToRight, parent=self)
47 | self.setLayout(form_lbx)
48 |
49 | self.le.setMaximumWidth(40)
50 |
51 | # 시그널 슬롯 연결
52 | self.sld.valueChanged.connect(self.valueChanged)
53 | self.le.textChanged.connect(self.sld.setValue)
54 | self.dial.valueChanged.connect(self.sld.setValue)
55 |
56 | form_lbx.addWidget(self.dial)
57 | form_lbx.addLayout(control_lbx)
58 | control_lbx.addWidget(self.sld)
59 | control_lbx.addWidget(self.le)
60 |
61 | @pyqtSlot(int, name="valueChanged")
62 | def value_changed(self, value):
63 | self.le.setText(str(value))
64 | self.dial.setValue(value)
65 |
66 | if __name__ == "__main__":
67 | app = QApplication(sys.argv)
68 | form = Form()
69 | form.show()
70 | exit(app.exec_())
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/QToolBar/QToolBar_01_sub_menu.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding: utf-8
3 |
4 | # 예제 내용
5 | # QToolBar.
6 |
7 | import sys
8 | from PyQt5.QtGui import QIcon
9 | from PyQt5.QtWidgets import QMainWindow
10 | from PyQt5.QtWidgets import QAction
11 | from PyQt5.QtWidgets import QToolBar
12 | from PyQt5.QtWidgets import QToolButton
13 | from PyQt5.QtWidgets import QMenu
14 | from PyQt5.QtWidgets import QLabel
15 | from PyQt5.QtWidgets import QApplication
16 |
17 |
18 | __author__ = "Deokyu Lim "
19 |
20 |
21 | class Window(QMainWindow):
22 | def __init__(self):
23 | QMainWindow.__init__(self)
24 | self.lb = QLabel()
25 | self.menu = QMenu(self)
26 | self.toolbar = QToolBar(self)
27 | self.tool_buttons = QToolButton(self)
28 | # 툴버튼이 팝업으로 메뉴를 지원할 수 있게 설정
29 | self.tool_buttons.setPopupMode(QToolButton.MenuButtonPopup)
30 | # 선택된 액션이 버튼 선택사항으로 나올 수 있게 트리거 설정 (필수)
31 | self.tool_buttons.triggered.connect(self.tool_buttons.setDefaultAction)
32 |
33 | self.init_window()
34 | self.init_toolbar()
35 |
36 | def init_window(self):
37 | self.setMinimumWidth(320)
38 | self.setMinimumHeight(240)
39 | self.setCentralWidget(self.lb)
40 |
41 | def init_toolbar(self):
42 | # 액션 생성
43 | action_1 = QAction(self)
44 | action_1.setText("QAction_1")
45 | action_1.setIcon(QIcon("assets/icon_split_horizontal.svg"))
46 | action_1.triggered.connect(lambda: self.lb.setText(action_1.text()))
47 |
48 | action_2 = QAction(self)
49 | action_2.setText("QAction_2")
50 | action_2.setIcon(QIcon("assets/icon_split_vertical.svg"))
51 | action_2.triggered.connect(lambda: self.lb.setText(action_2.text()))
52 |
53 | # 메뉴에 추가
54 | self.menu.addAction(action_1)
55 | self.menu.addAction(action_2)
56 |
57 | # 툴 버튼에 메뉴 설정
58 | self.tool_buttons.setMenu(self.menu)
59 | # 기본 사항으로 설정될 액션 선택 (필수)
60 | self.tool_buttons.setDefaultAction(action_1)
61 | self.toolbar.addWidget(self.tool_buttons)
62 | self.addToolBar(self.toolbar)
63 |
64 | if __name__ == "__main__":
65 | app = QApplication(sys.argv)
66 | form = Window()
67 | form.show()
68 | exit(app.exec_())
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/QLayout/QLayout_02_complex_layout.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding: utf-8
3 |
4 | # 예제 내용
5 | # * 기본 위젯을 사용하여 기본 창을 생성
6 | # * 부모 Layout 에 자식 Lyout을 배치
7 | # * Layout 배치시 정렬 설정
8 |
9 | import sys
10 |
11 | from PyQt5.QtWidgets import QWidget
12 | from PyQt5.QtWidgets import QLabel
13 | from PyQt5.QtWidgets import QBoxLayout
14 |
15 | from PyQt5.QtWidgets import QApplication
16 | from PyQt5.QtCore import Qt
17 |
18 | __author__ = "Deokyu Lim "
19 |
20 |
21 | class Form(QWidget):
22 | def __init__(self):
23 | QWidget.__init__(self, flags=Qt.Widget)
24 |
25 | # 배치될 위젯 변수 선언
26 | self.lb_1 = QLabel()
27 | self.lb_2 = QLabel()
28 | self.lb_3 = QLabel()
29 | self.lb_4 = QLabel()
30 | self.lb_5 = QLabel()
31 |
32 | # 레이아웃 선언 및 Form Widget에 설정
33 | self.layout_1 = QBoxLayout(QBoxLayout.LeftToRight, self)
34 | self.layout_2 = QBoxLayout(QBoxLayout.LeftToRight)
35 | self.layout_3 = QBoxLayout(QBoxLayout.TopToBottom)
36 |
37 | # 부모 레이아웃에 자식 레이아웃을 추가
38 | self.layout_1.addLayout(self.layout_2)
39 | self.layout_1.addLayout(self.layout_3)
40 |
41 | self.setLayout(self.layout_1)
42 | self.init_widget()
43 |
44 | def init_widget(self):
45 | self.setWindowTitle("Layout Basic")
46 | self.setFixedWidth(640)
47 | self.setFixedHeight(480)
48 |
49 | self.lb_1.setText("Label 1")
50 | self.lb_2.setText("Label 2")
51 | self.lb_3.setText("Label 3")
52 | self.lb_4.setText("Label 4")
53 | self.lb_5.setText("Label 5")
54 |
55 | self.lb_1.setStyleSheet("background-color: yellow")
56 | self.lb_2.setStyleSheet("background-color: red")
57 | self.lb_3.setStyleSheet("background-color: blue")
58 | self.lb_4.setStyleSheet("background-color: pink")
59 | self.lb_5.setStyleSheet("background-color: grey")
60 |
61 | self.layout_2.addWidget(self.lb_1)
62 | self.layout_2.addWidget(self.lb_2)
63 | self.layout_3.addWidget(self.lb_3)
64 | self.layout_3.addWidget(self.lb_4)
65 | self.layout_3.addWidget(self.lb_5)
66 |
67 |
68 | if __name__ == "__main__":
69 | app = QApplication(sys.argv)
70 | form = Form()
71 | form.show()
72 | exit(app.exec_())
73 |
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/QLineEdit/QLineEdit_01_input_mask.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding: utf-8
3 |
4 | # 예제 내용
5 | # * QLineEdit 기본 사용
6 |
7 | import sys
8 |
9 | from PyQt5.QtWidgets import QWidget
10 | from PyQt5.QtWidgets import QBoxLayout
11 | from PyQt5.QtWidgets import QLabel
12 | from PyQt5.QtWidgets import QLineEdit
13 | from PyQt5.QtWidgets import QComboBox
14 | from PyQt5.QtWidgets import QApplication
15 | from PyQt5.QtCore import Qt
16 | from PyQt5.QtCore import pyqtSlot
17 |
18 |
19 | __author__ = "Deokyu Lim "
20 |
21 | FORMAT = [
22 | {"name": "IP ADDRESS", "format": "000.000.000.000;"},
23 | {"name": "MAC ADDRESS", "format": "HH:HH:HH:HH:HH:HH;#"},
24 | {"name": "ISO DATE", "format": "0000-00-00;0"},
25 | {"name": "LICENSE NUMBER", "format": ">AAAAA-AAAAA-AAAAA-AAAAA-AAAAA;#"},
26 | ]
27 |
28 |
29 | class Form(QWidget):
30 | def __init__(self):
31 | QWidget.__init__(self, flags=Qt.Widget)
32 | self.cb = QComboBox()
33 | self.lb = QLabel()
34 | self.le = QLineEdit()
35 |
36 | self.init_widget()
37 |
38 | def init_widget(self):
39 | """
40 | 현재 위젯의 모양등을 초기화
41 | """
42 | self.setWindowTitle("QLineEdit Widget")
43 | form_lbx = QBoxLayout(QBoxLayout.TopToBottom, parent=self)
44 | self.setLayout(form_lbx)
45 |
46 | # 콤보박스에 아이템 이름과 userRole에 format 정보를 추가
47 | for item in FORMAT:
48 | self.cb.addItem(item["name"], item["format"])
49 |
50 | # 시그널 슬롯 처리
51 | self.cb.currentIndexChanged.connect(self.slot_change_format)
52 | self.le.textChanged.connect(self.lb.setText)
53 |
54 | form_lbx.addWidget(self.cb)
55 | form_lbx.addWidget(self.lb)
56 | form_lbx.addWidget(self.le)
57 |
58 | self.slot_change_format(0)
59 |
60 | @pyqtSlot(int)
61 | def slot_change_format(self, idx):
62 | # 콤보박스가 바뀔 때마다
63 | # 라인에디터 내용, 커서, 마스크 초기화
64 | # 라벨 내용 초기화
65 | # 포커스를 라인에디터가 가져감
66 | self.le.clear()
67 | self.le.setCursorPosition(0)
68 | self.le.setInputMask(self.cb.itemData(idx, Qt.UserRole))
69 | self.lb.clear()
70 | self.le.setFocus()
71 |
72 | if __name__ == "__main__":
73 | app = QApplication(sys.argv)
74 | form = Form()
75 | form.show()
76 | exit(app.exec_())
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/Signal_Slot/signal_slot_06_custom_slot.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding: utf-8
3 |
4 | # 예제 내용
5 | # * 사용자 정의 슬롯이 다양한 타입의 값을 받을 수 있게 만들기
6 |
7 | import sys
8 |
9 | from PyQt5.QtWidgets import QWidget
10 | from PyQt5.QtWidgets import QDial
11 | from PyQt5.QtWidgets import QSlider
12 | from PyQt5.QtWidgets import QLineEdit
13 | from PyQt5.QtWidgets import QApplication
14 | from PyQt5.QtWidgets import QBoxLayout
15 | from PyQt5.QtCore import Qt
16 | from PyQt5.QtCore import pyqtSlot
17 |
18 | __author__ = "Deokyu Lim "
19 |
20 |
21 | class CustomSlider(QSlider):
22 | def __init__(self, *args, **kwargs):
23 | QSlider.__init__(self, *args)
24 |
25 | @pyqtSlot(int, name="setValue")
26 | def set_int_value(self, value):
27 | QSlider.setValue(self, value)
28 |
29 | @pyqtSlot(str, name="setValue")
30 | def set_str_value(self, value):
31 | try:
32 | value = int(value) # 숫자 이외의 값이 들어오면 여기서 죽게된다.
33 | except Exception:
34 | value = 0
35 | QSlider.setValue(self, value)
36 |
37 |
38 | class Form(QWidget):
39 | def __init__(self):
40 | QWidget.__init__(self, flags=Qt.Widget)
41 | self.le = QLineEdit()
42 | self.dial = QDial()
43 | self.sld = CustomSlider(Qt.Horizontal)
44 |
45 | self.init_widget()
46 |
47 | def init_widget(self):
48 | self.setWindowTitle("Custom Slot")
49 | form_lbx = QBoxLayout(QBoxLayout.TopToBottom, parent=self)
50 | control_lbx = QBoxLayout(QBoxLayout.LeftToRight, parent=self)
51 | self.setLayout(form_lbx)
52 |
53 | self.le.setMaximumWidth(40)
54 |
55 | # 시그널 슬롯 연결
56 | self.sld.valueChanged.connect(self.valueChanged)
57 | self.le.textChanged.connect(self.sld.setValue)
58 | self.dial.valueChanged.connect(self.sld.setValue)
59 |
60 | form_lbx.addWidget(self.dial)
61 | form_lbx.addLayout(control_lbx)
62 | control_lbx.addWidget(self.sld)
63 | control_lbx.addWidget(self.le)
64 |
65 | @pyqtSlot(int, name="valueChanged")
66 | def value_changed(self, value):
67 | self.le.setText(str(value))
68 | self.dial.setValue(value)
69 |
70 | if __name__ == "__main__":
71 | app = QApplication(sys.argv)
72 | form = Form()
73 | form.show()
74 | exit(app.exec_())
--------------------------------------------------------------------------------
/QtFramework/QML/05-PyQt_QML_simple_examples/10-PyQt_QML_simple_example.qml:
--------------------------------------------------------------------------------
1 | import QtQuick 2.5
2 |
3 | // 사각형의 root 요소(Element)
4 | Rectangle {
5 | // 요소의 이름은 root
6 | id: root
7 |
8 | // 속성 정의
9 | width: 120; height: 240
10 |
11 | // 색 속성
12 | color: "#4A4A4A"
13 |
14 | // 하위 요소들 선언
15 | Image {
16 | id: triangle
17 |
18 | // 부모(root) 값 참조
19 | x: (parent.width - width)/2; y: 40
20 |
21 | source: 'assets/triangle_red.png'
22 | }
23 |
24 | // 다른 요소 선언
25 | Text {
26 | // 이름없이 사용가능
27 |
28 | // id값을 이용한 참조 가능
29 | y: triangle.y + triangle.height + 20
30 | width: root.width
31 |
32 | color: 'white'
33 | horizontalAlignment: Text.AlignHCenter
34 | text: 'Triangle'
35 | }
36 |
37 | Text {
38 | id: thisLabel
39 |
40 | x: 24; y: 16
41 | height: 2 * width
42 |
43 | // 사용자 속성 값 선언
44 | property int times: 24
45 |
46 | // 외부에서 접근 가능하게 별명 선언
47 | property alias anotherTimes: thisLabel.times
48 |
49 | // 텍스트 속성 설정, 값은 문자열과 사용자 속성 값
50 | text: "Greetings " + times
51 |
52 | // 폰트그룹 속성 정의
53 | font.family: "Ubuntu"
54 | font.pixelSize: 24
55 |
56 | // 키 네비게이션 설정
57 | KeyNavigation.tab: otherLabel
58 |
59 | // 길이가 달라질경우 signal 발생
60 | onHeightChanged: console.log('height:', height)
61 |
62 | // 키 이벤트는 focus 상태있때만
63 | focus: true
64 |
65 | // 포커스 상태에 따른 색 변화
66 | color: focus?"red":"black"
67 | }
68 |
69 | Text {
70 | id: label
71 |
72 | x: 24; y: 24
73 |
74 | // 스페이스바를 카운터할 속성
75 | property int spacePresses: 0
76 |
77 | text: "Space pressed: " + spacePresses + " times"
78 |
79 | // 글이 바뀌면 콘솔에 로그를 남긴다
80 | onTextChanged: console.log("text changed to:", text)
81 |
82 | // 포커스가 있어야 동작
83 | focus: true
84 |
85 | // 스페이스바를 누르면 함수 실행
86 | Keys.onSpacePressed: {
87 | increment()
88 | }
89 |
90 | // ESC키를 누르면 라벨 지우기
91 | Keys.onEscapePressed: {
92 | label.text = ''
93 | }
94 |
95 | // 자바 스크립트 함수
96 | function increment() {
97 | spacePresses = spacePresses + 1
98 | }
99 | }
100 | }
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/QComboBox/QComboBox_02_model_decoration.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding: utf-8
3 |
4 | # 예제 내용
5 | # * QComboBox 기본 사용
6 | # * ComboBox에 그림을 추가한다.
7 |
8 | import sys
9 |
10 | from PyQt5.QtWidgets import QWidget
11 | from PyQt5.QtWidgets import QBoxLayout
12 | from PyQt5.QtWidgets import QLabel
13 | from PyQt5.QtWidgets import QComboBox
14 | from PyQt5.QtWidgets import QApplication
15 | from PyQt5.QtCore import Qt
16 | from PyQt5.QtCore import QVariant
17 | from PyQt5.QtGui import QStandardItemModel
18 | from PyQt5.QtGui import QStandardItem
19 | from PyQt5.QtGui import QPixmap
20 |
21 | __author__ = "Deokyu Lim "
22 |
23 | IMAGE_PATH = "../../../Resources/Images/"
24 |
25 |
26 | class UserModel(QStandardItemModel):
27 | def __init__(self, data=None, parent=None):
28 | QStandardItemModel.__init__(self, parent)
29 | for i, d in enumerate(data):
30 | item = QStandardItem(d["name"])
31 | item.setData(d["image"], Qt.DecorationRole)
32 | self.setItem(i, 0, item)
33 |
34 | def data(self, QModelIndex, role=None):
35 | data = self.itemData(QModelIndex)
36 | if role == Qt.DisplayRole:
37 | return "%s" % (data[role])
38 | elif role in data and role == Qt.DecorationRole:
39 | return QPixmap(data[role]).scaledToHeight(25)
40 | elif role == Qt.UserRole:
41 | print(data[role])
42 | return QVariant()
43 |
44 |
45 | class Form(QWidget):
46 | def __init__(self):
47 | QWidget.__init__(self, flags=Qt.Widget)
48 | self.init_widget()
49 |
50 | def init_widget(self):
51 | self.setWindowTitle("QComboBox Widget")
52 | self.setMinimumWidth(150)
53 | form_lbx = QBoxLayout(QBoxLayout.TopToBottom, parent=self)
54 | self.setLayout(form_lbx)
55 |
56 | data = [
57 | {"name": "Apple", "image": IMAGE_PATH + "apple.jpg"},
58 | {"name": "Banana", "image": IMAGE_PATH + "banana.jpg"}
59 | ]
60 | model = UserModel(data)
61 |
62 | lb = QLabel()
63 |
64 | qb = QComboBox()
65 | qb.setModel(model)
66 | qb.currentTextChanged.connect(lb.setText) # 현재 인덱스의 데이터가 바뀔 때
67 |
68 | form_lbx.addWidget(qb)
69 | form_lbx.addWidget(lb)
70 |
71 |
72 | if __name__ == "__main__":
73 | app = QApplication(sys.argv)
74 | form = Form()
75 | form.show()
76 | exit(app.exec_())
77 |
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/ItemWidget_Item_based/ItemWidget_QTreeWidget_03_widget.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding: utf-8
3 |
4 | # 예제 내용
5 | # * QTreeWidget을 사용하여 아이템을 표시
6 |
7 | __author__ = "Deokyu Lim "
8 |
9 | from PyQt5.QtWidgets import QWidget
10 | from PyQt5.QtWidgets import QTreeWidget
11 | from PyQt5.QtWidgets import QSpinBox
12 | from PyQt5.QtCore import QVariant
13 | from PyQt5.QtWidgets import QTreeWidgetItem
14 | from PyQt5.QtWidgets import QApplication
15 | from PyQt5.QtWidgets import QBoxLayout
16 | from PyQt5.QtCore import Qt
17 |
18 |
19 | class Form(QWidget):
20 | def __init__(self):
21 | QWidget.__init__(self, flags=Qt.Widget)
22 | self.setWindowTitle("QTreeWidget Column")
23 | box = QBoxLayout(QBoxLayout.TopToBottom)
24 | self.setLayout(box)
25 |
26 | # QTreeView 생성 및 설정
27 | self.tw = QTreeWidget(self)
28 | box.addWidget(self.tw)
29 | self.tw.setColumnCount(2)
30 | self.tw.setHeaderLabels(["Properties", "Value"])
31 |
32 | root_1 = QTreeWidgetItem(self.tw)
33 | root_1.setText(0, "Option_1")
34 | root_1.setText(1, "Option_1 Description")
35 |
36 |
37 | item_1 = QTreeWidgetItem()
38 | item_1.setText(0, "enabled")
39 | item_1.setFlags(item_1.flags() | Qt.ItemIsUserCheckable)
40 | item_1.setCheckState(1, Qt.Checked)
41 | root_1.addChild(item_1)
42 |
43 | item_1 = QTreeWidgetItem()
44 | item_1.setText(0, "height")
45 | root_1.addChild(item_1)
46 | self.tw.setItemWidget(item_1, 1, QSpinBox())
47 |
48 | root_2 = QTreeWidgetItem(self.tw)
49 | root_2.setText(0, "Option_2")
50 | root_2.setText(1, "Option_2 Description")
51 |
52 | item_2 = QTreeWidgetItem()
53 | item_2.setText(0, "width")
54 | item_2.setText(1, "300")
55 | root_2.addChild(item_2)
56 |
57 | item_2 = QTreeWidgetItem()
58 | item_2.setText(0, "height")
59 | item_2.setText(1, "200")
60 | root_2.addChild(item_2)
61 |
62 |
63 | def add_tree_child(self, parent:QTreeWidgetItem, name:str, description:str):
64 | item = QTreeWidgetItem()
65 | item.setText(0, name)
66 | item.setText(1, description)
67 | parent.addChild(item)
68 | return item
69 |
70 |
71 | if __name__ == "__main__":
72 | import sys
73 | app = QApplication(sys.argv)
74 | form = Form()
75 | form.show()
76 | exit(app.exec_())
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/ItemViews_model_based/ItemViews_QTreeView_01_pixmap.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding: utf-8
3 |
4 | # 예제 내용
5 | # * QListView 기본 사용법
6 | # * QAbstractListModel 을 이용한 사용자 모델 생성
7 | # * 수정이 가능한 모델
8 |
9 | import sys
10 |
11 | from PyQt5.QtWidgets import QWidget
12 | from PyQt5.QtWidgets import QTreeView
13 | from PyQt5.QtWidgets import QAbstractItemView
14 | from PyQt5.QtCore import QVariant
15 | from PyQt5.QtGui import QStandardItemModel
16 | from PyQt5.QtGui import QStandardItem
17 | from PyQt5.QtGui import QPixmap
18 | from PyQt5.QtWidgets import QApplication
19 | from PyQt5.QtCore import Qt
20 |
21 | __author__ = "Deokyu Lim "
22 |
23 |
24 | class Model(QStandardItemModel):
25 | """
26 | 사용자 데이터 모델 설정
27 | [{"type":str, "objects":[str, ...]}, ...]
28 |
29 | """
30 | def __init__(self, data):
31 | QStandardItemModel.__init__(self)
32 | self._data = data
33 | for j, d in enumerate(data):
34 | item = QStandardItem(d["type"])
35 | for obj in d["objects"]:
36 | child = QStandardItem(obj)
37 | child.setData(d["picture"], Qt.DecorationRole) # Role 이름의 키 값을 가지게 될 데이터 정의
38 | item.appendRow(child)
39 | self.setItem(j, 0, item)
40 |
41 | def data(self, QModelIndex, role=None):
42 | # itemData에 인자값으로 받은 QModelIndex를 넣어주면 사전형태의 데이터 값을 돌려준다.
43 | data = self.itemData(QModelIndex)
44 |
45 | if role == Qt.DisplayRole:
46 | ret = data[role]
47 | elif role in data and role == Qt.DecorationRole:
48 | ret = QPixmap(data[role]).scaledToHeight(25)
49 | else:
50 | ret = QVariant()
51 | return ret
52 |
53 |
54 | class Form(QWidget):
55 | def __init__(self):
56 | QWidget.__init__(self, flags=Qt.Widget)
57 | self.setWindowTitle("ItemView QTreeView")
58 | self.setFixedWidth(210)
59 | self.setFixedHeight(150)
60 |
61 | data = [
62 | {"type": "Sword", "objects": ["Long Sword", "Short Sword"], "picture": "sword.png"},
63 | {"type": "Shield", "objects": ["Wood Shield", "iron Shied"], "picture": "shield.png"},
64 | ]
65 | # QTreeView 생성 및 설정
66 | view = QTreeView(self)
67 | view.setEditTriggers(QAbstractItemView.DoubleClicked)
68 |
69 | model = Model(data)
70 | view.setModel(model)
71 |
72 |
73 | if __name__ == "__main__":
74 | app = QApplication(sys.argv)
75 | form = Form()
76 | form.show()
77 | exit(app.exec_())
78 |
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/QTabWidget/QTabWidget_02_add_widget_in_tab.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding: utf-8
3 |
4 | # 예제 내용
5 | # * QTabWidget 탭에 다양한 위젯 추가
6 |
7 | import sys
8 |
9 | from PyQt5.QtWidgets import QWidget
10 | from PyQt5.QtWidgets import QBoxLayout
11 | from PyQt5.QtWidgets import QGroupBox
12 | from PyQt5.QtWidgets import QCheckBox
13 | from PyQt5.QtWidgets import QTextEdit
14 | from PyQt5.QtWidgets import QRadioButton
15 | from PyQt5.QtWidgets import QTabWidget
16 | from PyQt5.QtWidgets import QApplication
17 | from PyQt5.QtCore import Qt
18 |
19 | __author__ = "Deokyu Lim "
20 |
21 |
22 | class TabWidgetA(QWidget):
23 | def __init__(self, parent=None):
24 | super(TabWidgetA, self).__init__(parent=parent)
25 | self.init_widget()
26 |
27 | def init_widget(self):
28 | """
29 | 현재 위젯의 모양등을 초기화
30 | """
31 | self.setWindowTitle("Hello World")
32 | form_lbx = QBoxLayout(QBoxLayout.TopToBottom, parent=self)
33 | self.setLayout(form_lbx)
34 |
35 | gb_1 = QGroupBox(self)
36 | gb_1.setTitle("GroupBox")
37 | form_lbx.addWidget(gb_1)
38 | lbx = QBoxLayout(QBoxLayout.LeftToRight)
39 | gb_1.setLayout(lbx)
40 | lbx.addWidget(QCheckBox("check box #1"))
41 | lbx.addWidget(QCheckBox("check box #2"))
42 | lbx.addWidget(QCheckBox("check box #3"))
43 |
44 | gb_2 = QGroupBox(self)
45 | gb_2.setTitle("GroupBox")
46 | gb_2.setCheckable(True)
47 | gb_2.setChecked(False)
48 | form_lbx.addWidget(gb_2)
49 | lbx = QBoxLayout(QBoxLayout.LeftToRight)
50 | gb_2.setLayout(lbx)
51 | lbx.addWidget(QRadioButton("radio button #1"))
52 | lbx.addWidget(QRadioButton("radio button #2"))
53 | lbx.addWidget(QRadioButton("radio button #3"))
54 |
55 |
56 | class Form(QWidget):
57 | def __init__(self):
58 | QWidget.__init__(self, flags=Qt.Widget)
59 | self.tbw = QTabWidget()
60 | self.init_widget()
61 |
62 | def init_widget(self):
63 | """
64 | 현재 위젯의 모양등을 초기화
65 | """
66 | self.setWindowTitle("Tab Widget")
67 | form_lbx = QBoxLayout(QBoxLayout.TopToBottom, parent=self)
68 | self.setLayout(form_lbx)
69 | form_lbx.addWidget(self.tbw)
70 |
71 | self.tbw.addTab(TabWidgetA(), TabWidgetA.__name__)
72 | self.tbw.addTab(QTextEdit(), QTextEdit.__name__)
73 |
74 |
75 | if __name__ == "__main__":
76 | app = QApplication(sys.argv)
77 | form = Form()
78 | form.show()
79 | exit(app.exec_())
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/ItemViews_model_based/ItemViews_QTreeView_04_header.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding: utf-8
3 |
4 | # 예제 내용
5 | # * QListView 기본 사용법
6 | # * QAbstractListModel 을 이용한 사용자 모델 생성
7 | # * 수정이 가능한 모델
8 |
9 | import sys
10 |
11 | from PyQt5.QtWidgets import QWidget
12 | from PyQt5.QtWidgets import QTreeView
13 | from PyQt5.QtWidgets import QApplication
14 | from PyQt5.QtWidgets import QAbstractItemView
15 |
16 | from PyQt5.QtGui import QStandardItemModel
17 | from PyQt5.QtGui import QStandardItem
18 |
19 | from PyQt5.QtCore import Qt
20 |
21 |
22 | __author__ = "Deokyu Lim "
23 |
24 |
25 | class Model(QStandardItemModel):
26 | """
27 | 사용자 데이터 모델 설정
28 | [{"type":str, "objects":[str, ...]}, ...]
29 | 위의 데이터 형식을 이용하여 서브 아이템을 가지는 모델을 생성
30 |
31 | """
32 | def __init__(self, data):
33 | QStandardItemModel.__init__(self)
34 |
35 | d = data[0] # Fruit
36 | item = QStandardItem(d["type"])
37 | child = QStandardItem(d["objects"][0]) # Apple
38 | item.appendRow(child)
39 | child = QStandardItem(d["objects"][1]) # Banana
40 | item.appendRow(child)
41 | self.setItem(0, 0, item)
42 |
43 | d = data[1] # Vegetable
44 | item = QStandardItem(d["type"])
45 | child = QStandardItem(d["objects"][0]) # Carrot
46 | item.appendRow(child)
47 | child = QStandardItem(d["objects"][1]) # Tomato
48 | item.appendRow(child)
49 | self.setItem(1, 0, item)
50 |
51 | self.setHeaderData(0, Qt.Horizontal, "Type")
52 |
53 | # for 문을 이용해서 작성했을 경우
54 | # for j, _type in enumerate(data):
55 | # item = QStandardItem(_type["type"])
56 | # for obj in _type["objects"]:
57 | # child = QStandardItem(obj)
58 | # item.appendRow(child)
59 | # self.setItem(j, 0, item)
60 |
61 |
62 | class Form(QWidget):
63 | def __init__(self):
64 | QWidget.__init__(self, flags=Qt.Widget)
65 | self.setWindowTitle("ItemView QTreeView")
66 | self.setFixedWidth(210)
67 | self.setFixedHeight(150)
68 |
69 | # 데이터
70 | data = [
71 | {"type": "Fruit", "objects": ["Apple", "Banana"]},
72 | {"type": "Vegetable", "objects": ["Carrot", "Tomato"]},
73 | ]
74 | # QTreeView 생성 및 설정
75 | view = QTreeView(self)
76 | view.setEditTriggers(QAbstractItemView.DoubleClicked)
77 |
78 | model = Model(data)
79 | view.setModel(model)
80 |
81 |
82 | if __name__ == "__main__":
83 | app = QApplication(sys.argv)
84 | form = Form()
85 | form.show()
86 | exit(app.exec_())
87 |
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/ItemViews_model_based/ItemViews_QTreeView_00_basic.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding: utf-8
3 |
4 | # 예제 내용
5 | # * QListView 기본 사용법
6 | # * QAbstractListModel 을 이용한 사용자 모델 생성
7 | # * 수정이 가능한 모델
8 |
9 | import sys
10 |
11 | from PyQt5.QtWidgets import QWidget
12 | from PyQt5.QtWidgets import QTreeView
13 | from PyQt5.QtCore import QAbstractItemModel
14 | from PyQt5.QtWidgets import QAbstractItemView
15 | from PyQt5.QtCore import QVariant
16 | from PyQt5.QtGui import QStandardItemModel
17 | from PyQt5.QtGui import QStandardItem
18 | from PyQt5.QtWidgets import QApplication
19 | from PyQt5.QtCore import Qt
20 |
21 | __author__ = "Deokyu Lim "
22 |
23 |
24 | class Model(QStandardItemModel):
25 | """
26 | 사용자 데이터 모델 설정
27 | [{"type":str, "objects":[str, ...]}, ...]
28 | 위의 데이터 형식을 이용하여 서브 아이템을 가지는 모델을 생성
29 |
30 | """
31 | def __init__(self, data):
32 | QStandardItemModel.__init__(self)
33 |
34 | d = data[0] # Fruit
35 | item = QStandardItem(d["type"])
36 | child = QStandardItem(d["objects"][0]) # Apple
37 | item.appendRow(child)
38 | child = QStandardItem(d["objects"][1]) # Banana
39 | item.appendRow(child)
40 | self.setItem(0, 0, item)
41 |
42 | d = data[1] # Vegetable
43 | item = QStandardItem(d["type"])
44 | child = QStandardItem(d["objects"][0]) # Carrot
45 | item.appendRow(child)
46 | child = QStandardItem(d["objects"][1]) # Tomato
47 | item.appendRow(child)
48 | self.setItem(1, 0, item)
49 |
50 | # for 문을 이용해서 작성했을 경우
51 | # for j, _type in enumerate(data):
52 | # item = QStandardItem(_type["type"])
53 | # for obj in _type["objects"]:
54 | # child = QStandardItem(obj)
55 | # item.appendRow(child)
56 | # self.setItem(j, 0, item)
57 |
58 |
59 | class Form(QWidget):
60 | def __init__(self):
61 | QWidget.__init__(self, flags=Qt.Widget)
62 | self.setWindowTitle("ItemView QTreeView")
63 | self.setFixedWidth(210)
64 | self.setFixedHeight(150)
65 |
66 | # 데이터
67 | data = [
68 | {"type": "Fruit", "objects": ["Apple", "Banana"]},
69 | {"type": "Vegetable", "objects": ["Carrot", "Tomato"]},
70 | ]
71 | # QTreeView 생성 및 설정
72 | view = QTreeView(self)
73 | view.setEditTriggers(QAbstractItemView.DoubleClicked)
74 |
75 | model = Model(data)
76 | view.setModel(model)
77 |
78 |
79 | if __name__ == "__main__":
80 | app = QApplication(sys.argv)
81 | form = Form()
82 | form.show()
83 | exit(app.exec_())
84 |
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/Drag_and_Drop/drag_and_drop_02_keep_feature.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 |
3 | # 예제 내용
4 | # * 드래그 앤 드랍 사용
5 | # * 드래그시 위젯의 모양 표시
6 | # * 드랍시 마우스 포인터가 TopLeft가 아닌 그랩 포인트에 위치
7 |
8 | import sys
9 |
10 | from PyQt5.QtWidgets import QWidget
11 | from PyQt5.QtWidgets import QPushButton
12 | from PyQt5.QtWidgets import QApplication
13 | from PyQt5.QtCore import QPoint
14 |
15 | from PyQt5.QtGui import QDragEnterEvent
16 | from PyQt5.QtGui import QDropEvent
17 | from PyQt5.QtGui import QMouseEvent
18 | from PyQt5.QtGui import QDrag
19 | from PyQt5.QtGui import QPixmap
20 | from PyQt5.QtCore import Qt
21 |
22 | from PyQt5.QtCore import QMimeData
23 |
24 |
25 | __author__ = "Deokyu Lim "
26 |
27 |
28 | class Button(QPushButton):
29 | def __init__(self, title, parent):
30 | QPushButton.__init__(self, title, parent)
31 | self.offset = 0
32 |
33 | def mouseMoveEvent(self, e: QMouseEvent):
34 | # 왼쪽 버튼은 클릭용이므로 오른쪽 버튼 입력 허용
35 | if e.buttons() != Qt.RightButton:
36 | return
37 |
38 | # 데이터 전송을 위한 MIME 객체 선언
39 | # 데이터 타입, 보낼 데이터를 Bytes 형으로 저장
40 | mime_data = QMimeData()
41 | mime_data.setData("application/hotspot", b"%d %d" % (e.x(), e.y()))
42 |
43 | drag = QDrag(self)
44 | # MIME 타입데이터를 Drag에 설정
45 | drag.setMimeData(mime_data)
46 | # 드래그시 위젯의 모양 유지를 위해 QPixmap에 모양을 렌더링
47 | pixmap = QPixmap(self.size())
48 | self.render(pixmap)
49 | drag.setPixmap(pixmap)
50 |
51 | drag.setHotSpot(e.pos() - self.rect().topLeft())
52 | drag.exec_(Qt.MoveAction)
53 |
54 |
55 | class Form(QWidget):
56 | def __init__(self):
57 | QWidget.__init__(self, flags=Qt.Widget)
58 | self.setFixedSize(300, 300)
59 | self.btn = Button("Drag me to the moon", self)
60 | self.init_widget()
61 |
62 | def init_widget(self):
63 | """
64 | 현재 위젯의 모양등을 초기화
65 | """
66 | self.setWindowTitle("Drag and Drop")
67 | self.setAcceptDrops(True)
68 | self.btn.show()
69 |
70 | def dragEnterEvent(self, e: QDragEnterEvent):
71 | e.accept()
72 |
73 | def dropEvent(self, e: QDropEvent):
74 | position = e.pos()
75 |
76 | # 보내온 데이터를 받기
77 | # 그랩 당시의 마우스 위치값을 함께 계산하여 위젯 위치 보정
78 | offset = e.mimeData().data("application/hotspot")
79 | x, y = offset.data().decode('utf-8').split()
80 | self.btn.move(position - QPoint(int(x), int(y)))
81 |
82 | e.setDropAction(Qt.MoveAction)
83 | e.accept()
84 |
85 |
86 | if __name__ == "__main__":
87 | app = QApplication(sys.argv)
88 | form = Form()
89 | form.show()
90 | exit(app.exec_())
91 |
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/QComboBox/QComboBox_03_model_tableview.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding: utf-8
3 |
4 | # 예제 내용
5 | # * QComboBox 기본 사용
6 | # * ComboBox에 그림을 추가한다.
7 |
8 | import sys
9 |
10 | from PyQt5.QtWidgets import QWidget
11 | from PyQt5.QtWidgets import QBoxLayout
12 | from PyQt5.QtWidgets import QLabel
13 | from PyQt5.QtWidgets import QComboBox
14 | from PyQt5.QtWidgets import QTableView
15 | from PyQt5.QtWidgets import QApplication
16 | from PyQt5.QtCore import Qt
17 | from PyQt5.QtCore import QVariant
18 | from PyQt5.QtGui import QStandardItemModel
19 | from PyQt5.QtGui import QStandardItem
20 | from PyQt5.QtGui import QPixmap
21 |
22 | __author__ = "Deokyu Lim "
23 |
24 | IMAGE_PATH = "../../../Resources/Images/"
25 |
26 |
27 | class UserModel(QStandardItemModel):
28 | def __init__(self, data=None, parent=None):
29 | QStandardItemModel.__init__(self, parent)
30 | for i, d in enumerate(data):
31 | col_1 = QStandardItem(d["name"])
32 | col_2 = QStandardItem(d["image"])
33 | col_3 = QStandardItem(d["color"])
34 | self.setItem(i, 0, col_1)
35 | self.setItem(i, 1, col_2)
36 | self.setItem(i, 2, col_3)
37 | self.setHorizontalHeaderLabels(["Name", "Image", "Color"])
38 |
39 | def data(self, QModelIndex, role=None):
40 | data = self.itemData(QModelIndex)
41 | if role == Qt.DisplayRole:
42 | if QModelIndex.column() == 1: # 이미지 경로는 디스플레이 되지 않게 한다.
43 | return QVariant()
44 | return data[0]
45 | if role == Qt.DecorationRole:
46 | return QPixmap(data[0]).scaledToHeight(25)
47 | return QVariant()
48 |
49 |
50 | class Form(QWidget):
51 | def __init__(self):
52 | QWidget.__init__(self, flags=Qt.Widget)
53 | self.init_widget()
54 |
55 | def init_widget(self):
56 | self.setWindowTitle("QComboBox Widget")
57 | self.setMinimumWidth(350)
58 | form_lbx = QBoxLayout(QBoxLayout.TopToBottom, parent=self)
59 | self.setLayout(form_lbx)
60 |
61 | data = [
62 | {"name": "Apple", "image": IMAGE_PATH + "apple.jpg", "color": "Red"},
63 | {"name": "Banana", "image": IMAGE_PATH + "banana.jpg", "color": "Yellow"}
64 | ]
65 |
66 | model = UserModel(data)
67 |
68 | qb = QComboBox()
69 | view = QTableView()
70 | view.setSelectionBehavior(view.SelectRows) # 한 줄 단위로 선택
71 |
72 | qb.setView(view)
73 | qb.setModel(model)
74 |
75 | form_lbx.addWidget(qb)
76 |
77 |
78 | if __name__ == "__main__":
79 | app = QApplication(sys.argv)
80 | form = Form()
81 | form.show()
82 | exit(app.exec_())
83 |
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/Signal_Slot/signal_slot_03_custom_signal.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding: utf-8
3 |
4 | # 예제 내용
5 | # * 시그널 선언시 인자 타입을 선언 후 값 전달하기
6 |
7 | import sys
8 |
9 | from PyQt5.QtWidgets import QWidget
10 | from PyQt5.QtWidgets import QLabel
11 | from PyQt5.QtWidgets import QApplication
12 | from PyQt5.QtWidgets import QBoxLayout
13 | from PyQt5.QtCore import Qt
14 | from PyQt5.QtCore import QThread
15 | from PyQt5.QtCore import pyqtSignal
16 | import string
17 | import time
18 | import random
19 | __author__ = "Deokyu Lim "
20 |
21 |
22 | class OtpTokenGenerator(QThread):
23 | """
24 | 1초마다 남은 시간
25 | 5초마다 변화된 OTP 코드를 시그널로 전달
26 | """
27 | # 사용자 정의 시그널 선언
28 | value_changed = pyqtSignal(str, name="ValueChanged")
29 | expires_in = pyqtSignal(int, name="ExpiresIn")
30 |
31 | EXPIRE_TIME = 5
32 |
33 | def __init__(self):
34 | QThread.__init__(self)
35 | self.characters = list(string.ascii_uppercase)
36 | self.token = self.generate()
37 |
38 | def __del__(self):
39 | self.wait()
40 |
41 | def generate(self):
42 | random.shuffle(self.characters)
43 | return ''.join(self.characters[0:5])
44 |
45 | def run(self):
46 | """
47 | 토큰 값과 남은 시간을 실시간으로 전송(emit)한다.
48 | :return:
49 | """
50 | self.value_changed.emit(self.token) # 시작 후 첫 OTP코드 전달
51 | while True:
52 | t = int(time.time()) % self.EXPIRE_TIME
53 | self.expires_in.emit(self.EXPIRE_TIME - t) # 남은 시간을 전달
54 | if t != 0:
55 | self.usleep(1)
56 | continue
57 | # 바뀐 토큰 값을 전달
58 | self.token = self.generate()
59 | self.value_changed.emit(self.token)
60 | self.msleep(1000)
61 |
62 |
63 | class Form(QWidget):
64 | def __init__(self):
65 | QWidget.__init__(self, flags=Qt.Widget)
66 | self.lb_token = QLabel()
67 | self.lb_expire_time = QLabel()
68 | self.otp_gen = OtpTokenGenerator()
69 | self.init_widget()
70 | self.otp_gen.start()
71 |
72 | def init_widget(self):
73 | self.setWindowTitle("Custom Signal")
74 | form_lbx = QBoxLayout(QBoxLayout.TopToBottom, parent=self)
75 | self.setLayout(form_lbx)
76 |
77 | # 시그널 슬롯 연결
78 | self.otp_gen.ValueChanged.connect(self.lb_token.setText)
79 | self.otp_gen.ExpiresIn.connect(lambda v: self.lb_expire_time.setText(str(v)))
80 |
81 | form_lbx.addWidget(self.lb_token)
82 | form_lbx.addWidget(self.lb_expire_time)
83 |
84 |
85 |
86 | if __name__ == "__main__":
87 | app = QApplication(sys.argv)
88 | form = Form()
89 | form.show()
90 | exit(app.exec_())
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/QLayout/QLayout_03_complex_layout.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding: utf-8
3 |
4 | # 예제 내용
5 | # * 기본 위젯을 사용하여 기본 창을 생성
6 | # * 다양한 레이아웃 위젯 사용
7 |
8 | import sys
9 |
10 | from PyQt5.QtWidgets import QWidget
11 | from PyQt5.QtWidgets import QLabel
12 | from PyQt5.QtWidgets import QSpacerItem
13 | from PyQt5.QtWidgets import QLineEdit
14 | from PyQt5.QtWidgets import QTextEdit
15 | from PyQt5.QtWidgets import QPushButton
16 | from PyQt5.QtWidgets import QGroupBox
17 |
18 | from PyQt5.QtWidgets import QBoxLayout
19 | from PyQt5.QtWidgets import QHBoxLayout
20 | from PyQt5.QtWidgets import QGridLayout
21 | from PyQt5.QtWidgets import QFormLayout
22 |
23 | from PyQt5.QtWidgets import QApplication
24 | from PyQt5.QtCore import Qt
25 |
26 | __author__ = "Deokyu Lim "
27 |
28 |
29 | class Form(QWidget):
30 | def __init__(self):
31 | QWidget.__init__(self, flags=Qt.Widget)
32 |
33 | self.setWindowTitle("Various Layout Widgets")
34 | self.setFixedWidth(640)
35 | self.setFixedHeight(480)
36 |
37 | layout_base = QBoxLayout(QBoxLayout.TopToBottom, self)
38 | self.setLayout(layout_base)
39 |
40 | # 첫 번째 그룹 QBoxLayout
41 | grp_1 = QGroupBox("QBoxLayout")
42 | layout_base.addWidget(grp_1)
43 | layout = QHBoxLayout()
44 | layout.addWidget(QPushButton("Butoon 1"))
45 | layout.addWidget(QPushButton("Butoon 1"))
46 | layout.addWidget(QPushButton("Butoon 1"))
47 | grp_1.setLayout(layout)
48 |
49 | # 두 번째 그룹 QGridLayout
50 | grp_2 = QGroupBox("QGridLayout")
51 | layout_base.addWidget(grp_2)
52 | grp_2_layout = QBoxLayout(QBoxLayout.LeftToRight)
53 | grp_2.setLayout(grp_2_layout)
54 | layout = QGridLayout()
55 | layout.addItem(QSpacerItem(10, 100))
56 | layout.addWidget(QLabel("Line Edit 1:"), 1, 0)
57 | layout.addWidget(QLabel("Line Edit 2:"), 2, 0)
58 | layout.addWidget(QLabel("Line Edit 2:"), 3, 0)
59 | layout.addWidget(QLineEdit(), 1, 1)
60 | layout.addWidget(QLineEdit(), 2, 1)
61 | layout.addWidget(QLineEdit(), 3, 1)
62 | grp_2_layout.addLayout(layout)
63 | grp_2_layout.addWidget(QTextEdit())
64 |
65 | # 세 번째 그룹 QFormLaytout
66 | grp_3 = QGroupBox("QFormLaytout")
67 | layout_base.addWidget(grp_3)
68 | layout = QFormLayout()
69 | grp_3.setLayout(layout)
70 | layout.addRow(QLabel("Line Edit 1:"), QLineEdit())
71 | layout.addRow(QLabel("Line Edit 2:"), QLineEdit())
72 | layout.addRow(QLabel("Line Edit 3:"), QLineEdit())
73 |
74 |
75 | if __name__ == "__main__":
76 | app = QApplication(sys.argv)
77 | form = Form()
78 | form.show()
79 | exit(app.exec_())
80 |
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/QSplitter/QSplitter_01_tab_split.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding: utf-8
3 |
4 | # 예제 내용
5 | # * 기본 위젯을 사용하여 기본 창을 생성
6 | # * '창 이름'을 변경한다.
7 |
8 | import sys
9 |
10 | from PyQt5.QtWidgets import QWidget
11 | from PyQt5.QtWidgets import QSplitter
12 | from PyQt5.QtWidgets import QTextEdit
13 | from PyQt5.QtWidgets import QBoxLayout
14 | from PyQt5.QtWidgets import QPushButton
15 |
16 | from PyQt5.QtWidgets import QApplication
17 | from PyQt5.QtCore import Qt
18 |
19 | from PyQt5.QtWidgets import QTabWidget
20 |
21 | __author__ = "Deokyu Lim "
22 |
23 |
24 | class Form(QWidget):
25 | """
26 | 만들고자 하는 프로그램의 기본이 되는 창 또는 폼 위젯.
27 | 본 위젯 위에 다른 위젯을 올려서 모양을 만든다.
28 |
29 | QWidget을 상속받아서 필요한 메소드를 작성.
30 | """
31 |
32 | def __init__(self):
33 | """
34 | 보통 __init__ (생성자)에서 필요한 것들을 다를 위젯들을 선언해줘도 되지만 init_widget을 따로 만들어서 호출한다.
35 | """
36 | QWidget.__init__(self, flags=Qt.Widget)
37 |
38 | self.te_1 = QTextEdit("1")
39 | self.te_2 = QTextEdit("2")
40 | self.te_3 = QTextEdit("3")
41 | self.pb = QPushButton("->")
42 |
43 | # 이 Splitter에 속한 위젯들은 Splitter Handler에 의해
44 | # 겹치기 및 크기 조절이 가능해 진다.
45 | self.splits = QSplitter()
46 | self.splits.setOrientation(Qt.Horizontal)
47 |
48 | self.tabs = list()
49 |
50 | # 전체 레이아웃
51 | self.vbox = QBoxLayout(QBoxLayout.TopToBottom)
52 | self.init_widget()
53 |
54 | def init_widget(self):
55 | """
56 | 현재 위젯의 모양등을 초기화
57 | """
58 | self.setWindowTitle("Splitter")
59 |
60 | # 한 개의 탭을 생성하여 위젯을 담는다.
61 | self.tabs.append(QTabWidget())
62 | self.tabs[0].addTab(self.te_1,"1")
63 | self.tabs[0].addTab(self.te_2,"2")
64 | self.tabs[0].addTab(self.te_3,"3")
65 |
66 | # 생성한 탭을 Splitter에 등록
67 | self.splits.addWidget(self.tabs[0])
68 | # 전체 레이아웃에 위젯 등록
69 | self.vbox.addWidget(self.splits)
70 | self.vbox.addWidget(self.pb)
71 | self.setLayout(self.vbox)
72 |
73 | self.pb.clicked.connect(self.split)
74 |
75 | def split(self):
76 | if 1 == len(self.tabs[0]):
77 | return
78 | # '첫번째 탭 위젯'에서 현제 선택된 위젯의 인덱스와 이름을 가져온다.
79 | name = self.tabs[0].tabText(self.tabs[0].currentIndex())
80 | widget = self.tabs[0].currentWidget()
81 | # '새로운 탭 위젯'을 생성하고 이동시킬 위젯을 새 탭으로 넣는다.
82 | self.tabs.append(QTabWidget())
83 | self.tabs[-1].addTab(widget, name)
84 | # '새로 생성한 탭 위젯'을 Splitter에 추가
85 | self.splits.addWidget(self.tabs[-1])
86 |
87 |
88 | if __name__ == "__main__":
89 | app = QApplication(sys.argv)
90 | form = Form()
91 | form.show()
92 | exit(app.exec_())
93 |
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/ItemViews_model_based/ItemViews_QTreeView_05_header.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding: utf-8
3 |
4 | # 예제 내용
5 | # * QListView 기본 사용법
6 | # * QAbstractListModel 을 이용한 사용자 모델 생성
7 | # * 수정이 가능한 모델
8 |
9 | import sys
10 |
11 | from PyQt5.QtWidgets import QWidget
12 | from PyQt5.QtWidgets import QTreeView
13 | from PyQt5.QtWidgets import QAbstractItemView
14 | from PyQt5.QtWidgets import QApplication
15 |
16 | from PyQt5.QtGui import QStandardItemModel
17 | from PyQt5.QtGui import QStandardItem
18 |
19 | from PyQt5.QtCore import Qt
20 |
21 |
22 | __author__ = "Deokyu Lim "
23 |
24 |
25 | class Model(QStandardItemModel):
26 | """
27 | 사용자 데이터 모델 설정
28 | [{"type":str, "objects":[str, ...]}, ...]
29 | 위의 데이터 형식을 이용하여 서브 아이템을 가지는 모델을 생성
30 |
31 | """
32 | def __init__(self, data):
33 | """
34 | # -- Type -- Color
35 | |-- item_type(Fruit)
36 | | |-- name(Apple) -- color(Red)
37 | | |-- name(Banana) -- color(Yellow)
38 | |-- item_type(
39 | :param data:
40 | """
41 | QStandardItemModel.__init__(self, 0, 2)
42 |
43 | # 하나의 아이템만 받도록 되어 있음
44 | self.setHeaderData(0, Qt.Horizontal, "Type")
45 | self.setHeaderData(1, Qt.Horizontal, "Color")
46 |
47 | row_items = list()
48 | column_items = list()
49 | item_type = data[0]['type']
50 | name, color = data[0]['objects'][0]
51 |
52 | item = QStandardItem(item_type)
53 |
54 | child = QStandardItem(name)
55 | row_items.append(child)
56 | column = QStandardItem(color)
57 | column_items.append(column)
58 |
59 | name, color = data[0]['objects'][1]
60 | child = QStandardItem(name)
61 | row_items.append(child)
62 | column = QStandardItem(color)
63 | column_items.append(column)
64 |
65 | item.appendRows(row_items)
66 | item.appendColumn(column_items)
67 | self.setItem(0, 0, item)
68 |
69 |
70 | class Form(QWidget):
71 | def __init__(self):
72 | QWidget.__init__(self, flags=Qt.Widget)
73 | self.setWindowTitle("ItemView QTreeView")
74 | self.setFixedWidth(210)
75 | self.setFixedHeight(150)
76 |
77 | # 데이터
78 | data = [
79 | {
80 | "type": "Fruit",
81 | "objects": [("Apple", "Red"), ("Banana", "Yellow")]},
82 | ]
83 | # QTreeView 생성 및 설정
84 | view = QTreeView(self)
85 | view.setEditTriggers(QAbstractItemView.DoubleClicked)
86 |
87 | model = Model(data)
88 | view.setModel(model)
89 |
90 |
91 | if __name__ == "__main__":
92 | app = QApplication(sys.argv)
93 | form = Form()
94 | form.show()
95 | exit(app.exec_())
96 |
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/ItemWidget_Item_based/ItemWidget_QTreeWidget_05_properties_editor_trees.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding: utf-8
3 |
4 | # 예제 내용
5 | # * QTreeWidget을 사용하여 아이템을 표시
6 |
7 | __author__ = "Deokyu Lim "
8 |
9 | from PyQt5.QtWidgets import QWidget
10 | from PyQt5.QtWidgets import QTreeWidget
11 | from PyQt5.QtWidgets import QSpinBox
12 | from PyQt5.QtCore import QVariant
13 | from PyQt5.QtWidgets import QTreeWidgetItem
14 | from PyQt5.QtWidgets import QApplication
15 | from PyQt5.QtWidgets import QBoxLayout
16 | from PyQt5.QtCore import Qt
17 |
18 |
19 | class Properties(dict):
20 | def __init__(self, *args, **kwargs):
21 | dict.__init__(self, *args, **kwargs)
22 |
23 |
24 | class ScenarioProperties(Properties):
25 | def __init__(self, data):
26 | super(ScenarioProperties, self).__init__(self)
27 |
28 |
29 |
30 |
31 | class Form(QWidget):
32 | def __init__(self):
33 | QWidget.__init__(self, flags=Qt.Widget)
34 | self.setWindowTitle("QTreeWidget Column")
35 | box = QBoxLayout(QBoxLayout.TopToBottom)
36 | self.setLayout(box)
37 |
38 | # QTreeView 생성 및 설정
39 | self.tw = QTreeWidget(self)
40 | box.addWidget(self.tw)
41 | self.tw.setColumnCount(2)
42 | self.tw.setHeaderLabels(["Properties", "Value"])
43 |
44 | root_1 = QTreeWidgetItem(self.tw)
45 | root_1.setText(0, "Option_1")
46 | root_1.setText(1, "Option_1 Description")
47 |
48 |
49 | item_1 = QTreeWidgetItem()
50 | item_1.setText(0, "enabled")
51 | item_1.setFlags(item_1.flags() | Qt.ItemIsUserCheckable)
52 | item_1.setCheckState(1, Qt.Checked)
53 | root_1.addChild(item_1)
54 |
55 | item_1 = QTreeWidgetItem()
56 | item_1.setText(0, "height")
57 | root_1.addChild(item_1)
58 | self.tw.setItemWidget(item_1, 1, QSpinBox())
59 |
60 | root_2 = QTreeWidgetItem(self.tw)
61 | root_2.setText(0, "Option_2")
62 | root_2.setText(1, "Option_2 Description")
63 |
64 | item_2 = QTreeWidgetItem()
65 | item_2.setText(0, "width")
66 | item_2.setText(1, "300")
67 | root_2.addChild(item_2)
68 |
69 | item_2 = QTreeWidgetItem()
70 | item_2.setText(0, "height")
71 | item_2.setText(1, "200")
72 | root_2.addChild(item_2)
73 |
74 |
75 | def add_tree_child(self, parent:QTreeWidgetItem, name:str, description:str):
76 | item = QTreeWidgetItem()
77 | item.setText(0, name)
78 | item.setText(1, description)
79 | parent.addChild(item)
80 | return item
81 |
82 |
83 | if __name__ == "__main__":
84 | import sys
85 | app = QApplication(sys.argv)
86 | form = Form()
87 | form.show()
88 | exit(app.exec_())
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/ItemViews_model_based/ItemViews_QListView_02_user_list_model.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding: utf-8
3 |
4 | # 예제 내용
5 | # * QListView 기본 사용법
6 | # * QAbstractListModel 을 이용한 사용자 모델 생성
7 | # * 수정이 가능한 모델
8 |
9 | import sys
10 |
11 | from PyQt5.QtWidgets import QWidget
12 | from PyQt5.QtWidgets import QListView
13 | from PyQt5.QtCore import QAbstractListModel
14 | from PyQt5.QtWidgets import QAbstractItemView
15 | from PyQt5.QtCore import QVariant
16 | from PyQt5.QtWidgets import QApplication
17 | from PyQt5.QtCore import Qt
18 |
19 | __author__ = "Deokyu Lim "
20 |
21 |
22 | class UserModel(QAbstractListModel):
23 | """
24 | ListModel은 두 가지의 필수 메소드를 작성해야 한다.
25 | int rowCount(self, parent=None, *args, **kwargs)
26 | QVariant data(self, QModelIndex, role=None)
27 | """
28 | def __init__(self, data=None, parent=None):
29 | QAbstractListModel.__init__(self, parent)
30 | self._data = data
31 |
32 | def rowCount(self, parent=None, *args, **kwargs):
33 | """
34 | 데이터의 개 수를 반환
35 | """
36 | return len(self._data)
37 |
38 | def data(self, QModelIndex, role=None):
39 | """
40 | 어떠한 이벤트가 일어났을 때 View가 Model.data를 호출
41 | View의 요구를 role을 참고하여 해당하는 값을 반환
42 | 해당하는 role에 대한 대응이 없을 경우 QVariant를 반환
43 | """
44 | item = self._data[QModelIndex.row()]
45 |
46 | if role == Qt.DisplayRole: # 값 출력시
47 | return "%s" % item['name']
48 | elif role == Qt.EditRole: # 값 수정시
49 | return "%s" % item['name']
50 | return QVariant()
51 |
52 | def flags(self, QModelIndex):
53 | """
54 | 모델 아이템별에 대한 정책
55 | """
56 | return Qt.ItemIsEditable | Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsTristate
57 |
58 | def setData(self, QModelIndex, value, role=None):
59 | """
60 | 값 수정시 호출
61 | """
62 | self._data[QModelIndex.row()]['name'] = value
63 | return True
64 |
65 |
66 | class Form(QWidget):
67 | def __init__(self):
68 | QWidget.__init__(self, flags=Qt.Widget)
69 | self.setWindowTitle("ItemView QListView")
70 | self.setFixedWidth(210)
71 | self.setFixedHeight(100)
72 |
73 | fruits = [
74 | {"name": "banana", "color": "yellow", "bg_color": "yellow"},
75 | {"name": "apple", "color": "red", "bg_color": "red"},
76 | {"name": "pear", "color": "green", "bg_color": "gray"},
77 | ]
78 |
79 | view = QListView(self)
80 | view.setEditTriggers(QAbstractItemView.DoubleClicked)
81 |
82 | model = UserModel(fruits)
83 | view.setModel(model)
84 |
85 |
86 | if __name__ == "__main__":
87 | app = QApplication(sys.argv)
88 | form = Form()
89 | form.show()
90 | exit(app.exec_())
91 |
--------------------------------------------------------------------------------
/Projects/SceenCapture/v0/capture.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding: utf-8
3 |
4 | # 스크린 캡쳐를 하는 프로그램 제작
5 |
6 | from PyQt5.QtWidgets import QWidget
7 | from PyQt5.QtWidgets import QLabel
8 | from PyQt5.QtWidgets import QVBoxLayout
9 | from PyQt5.QtWidgets import QPushButton
10 |
11 | from PyQt5.QtGui import QPixmap
12 | from PyQt5.QtGui import QGuiApplication
13 | from PyQt5.QtGui import QScreen
14 |
15 | from PyQt5.QtGui import QWindow
16 | from PyQt5.QtGui import QResizeEvent
17 | from PyQt5.QtCore import QSize
18 |
19 | from PyQt5.QtWidgets import QSizePolicy
20 | from PyQt5.QtCore import Qt
21 |
22 | from PyQt5.QtWidgets import QApplication
23 |
24 |
25 | class UI(QWidget):
26 | def __init__(self):
27 | QWidget.__init__(self)
28 | self.lb_captured_screen = QLabel(self)
29 | self.lb_captured_screen.setSizePolicy(
30 | QSizePolicy.Expanding, QSizePolicy.Expanding)
31 | self.lb_captured_screen.setStyleSheet("background-color: red")
32 | self.lb_captured_screen.setAlignment(Qt.AlignHCenter|Qt.AlignVCenter)
33 | screen_geometry = QApplication.desktop().screenGeometry(self)
34 | self.lb_captured_screen.setMinimumSize(
35 | screen_geometry.width() / 8, screen_geometry.height() / 8)
36 |
37 | self.captured_pixmap = QPixmap()
38 | self.pb = QPushButton("Capture Screen")
39 | vlayout = QVBoxLayout(self)
40 | vlayout.addWidget(self.lb_captured_screen)
41 | vlayout.addWidget(self.pb)
42 |
43 |
44 | class Form(UI):
45 | def __init__(self):
46 | UI.__init__(self)
47 | self.pb.clicked.connect(self.capture)
48 | self.capture()
49 |
50 | def resizeEvent(self, event: QResizeEvent):
51 | scale_size: QSize = self.captured_pixmap.size()
52 | scale_size.scale(self.lb_captured_screen.size(), Qt.KeepAspectRatio)
53 |
54 | if not self.lb_captured_screen.pixmap() \
55 | or scale_size != self.lb_captured_screen.pixmap().size():
56 | self.update_screen_capture()
57 | UI.resizeEvent(self, event)
58 |
59 | def capture(self):
60 | self.hide()
61 | screen: QScreen = QGuiApplication.primaryScreen()
62 | window: QWindow = self.windowHandle()
63 | if window:
64 | screen = window.screen()
65 | if not screen:
66 | return
67 |
68 | self.captured_pixmap: QPixmap = screen.grabWindow(0)
69 | self.update_screen_capture()
70 | self.show()
71 |
72 | def update_screen_capture(self):
73 | self.lb_captured_screen.setPixmap(self.captured_pixmap.scaled(
74 | self.lb_captured_screen.size(),
75 | Qt.KeepAspectRatio, Qt.SmoothTransformation))
76 |
77 |
78 | if "__main__"== __name__:
79 | import sys
80 | app = QApplication(sys.argv)
81 | form = Form()
82 | form.show()
83 | exit(app.exec_())
84 |
85 |
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/ItemWidget_Item_based/ItemWidget_QTreeWidget_04_properties_editor.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding: utf-8
3 |
4 | # 예제 내용
5 | # * QTreeWidget을 사용하여 아이템을 표시
6 |
7 | __author__ = "Deokyu Lim "
8 |
9 | from collections import defaultdict
10 |
11 | from PyQt5.QtWidgets import QWidget
12 | from PyQt5.QtCore import QObject
13 | from PyQt5.QtWidgets import QTreeWidget
14 | from PyQt5.QtWidgets import QSpinBox
15 | from PyQt5.QtWidgets import QTreeWidgetItem
16 | from PyQt5.QtWidgets import QApplication
17 | from PyQt5.QtWidgets import QBoxLayout
18 | from PyQt5.QtCore import Qt
19 | from PyQt5.QtCore import pyqtSlot
20 | from PyQt5.QtCore import qDebug
21 |
22 |
23 | class Properties(QObject):
24 | def __init__(self, widget: QTreeWidget):
25 | super(Properties, self).__init__()
26 | self.root = widget.invisibleRootItem()
27 | self.data = {
28 | "metadata": {
29 | "version": "1.0.0",
30 | "related_date": {
31 | "created": 1520413079,
32 | "last_modified": 1520413079},
33 | "related_people": {
34 | "author": {
35 | "name": "Raven",
36 | "email": "hong18s@gmail.net"
37 | },
38 | "last_modified_by": {
39 | "name": "Deokyu",
40 | "emil": "hong18s@gmail.com"
41 | }
42 | },
43 | "comment": "PyQt TreeWidget Example"
44 | },
45 | }
46 |
47 | def recursive_set_item_field(self, parent: QTreeWidgetItem, data, depth=0):
48 | for d in list(data.keys()):
49 | item = QTreeWidgetItem()
50 | item.setText(0, d)
51 | if isinstance(data[d], dict):
52 | self.recursive_set_item_field(item, data[d], depth+1)
53 | elif isinstance(data[d], list):
54 | pass
55 | else:
56 | item.setText(1, str(data[d]))
57 | parent.addChild(item)
58 | return
59 |
60 |
61 | class Form(QWidget):
62 | def __init__(self):
63 | QWidget.__init__(self, flags=Qt.Widget)
64 | self.setWindowTitle("QTreeWidget Example")
65 | box = QBoxLayout(QBoxLayout.TopToBottom)
66 | self.setLayout(box)
67 |
68 | # QTreeView 생성 및 설정
69 | self.tw = QTreeWidget(self)
70 | box.addWidget(self.tw)
71 | self.props = Properties(self.tw)
72 | self.tw.setColumnCount(2)
73 | self.tw.setHeaderLabels(["Properties", "Value"])
74 |
75 | self.props.recursive_set_item_field(
76 | self.props.root, self.props.data)
77 |
78 |
79 | if __name__ == "__main__":
80 | import sys
81 |
82 | app = QApplication(sys.argv)
83 | form = Form()
84 | form.show()
85 | exit(app.exec_())
86 |
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/QWebEngineView/QWebEngineView_02_WebChannel.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding: utf-8
3 |
4 | # 예제 내용
5 | # * Qt와 Javascript을 연결하여 웹을 제어
6 |
7 | import sys
8 |
9 | from PyQt5.QtWidgets import QWidget
10 | from PyQt5.QtWidgets import QBoxLayout
11 |
12 | from PyQt5.QtWidgets import QApplication
13 |
14 | from PyQt5.QtCore import Qt
15 | from PyQt5.QtCore import QDir
16 |
17 | from PyQt5.QtWidgets import QTextEdit
18 | from PyQt5.QtWidgets import QPushButton
19 |
20 | from PyQt5.QtWebEngineWidgets import QWebEngineView
21 | from PyQt5.QtWebChannel import QWebChannel
22 |
23 | from PyQt5.QtCore import QObject
24 | from PyQt5.QtCore import QUrl
25 | from PyQt5.QtCore import pyqtSignal
26 | from PyQt5.QtCore import pyqtSlot
27 |
28 | __author__ = "Deokyu Lim "
29 |
30 |
31 | class CallHandler(QObject):
32 | """
33 | 콜 핸들러 클래스는 Js와 통신하는 부분을 분리 목적
34 | """
35 | get_text = pyqtSignal(str, name="getText")
36 |
37 | @pyqtSlot(str, name='setText')
38 | def set_text(self, v):
39 | print(v)
40 |
41 |
42 | class Form(QWidget):
43 | def __init__(self):
44 | QWidget.__init__(self, flags=Qt.Widget)
45 |
46 | # 레이아웃 선언 및 Form Widget에 설정
47 | self.layout_1 = QBoxLayout(QBoxLayout.LeftToRight, self)
48 | self.layout_2 = QBoxLayout(QBoxLayout.LeftToRight)
49 | self.layout_3 = QBoxLayout(QBoxLayout.TopToBottom)
50 |
51 | # 부모 레이아웃에 자식 레이아웃을 추가
52 | self.layout_1.addLayout(self.layout_2)
53 | self.layout_1.addLayout(self.layout_3)
54 |
55 | self.web = QWebEngineView()
56 | self.pb_1 = QPushButton("요청하기")
57 | self.te_1 = QTextEdit()
58 |
59 | # Web과 통신할 수 있게 채널링
60 | channel = QWebChannel(self.web.page())
61 | self.web.page().setWebChannel(channel)
62 | self.handler = CallHandler() # 반드시 인스턴스 변수로 사용해야 한다.
63 | channel.registerObject('handler', self.handler) # js에서 불리울 이름
64 |
65 | self.setLayout(self.layout_1)
66 | self.init_widget()
67 |
68 | def init_widget(self):
69 | self.setWindowTitle("QWebChannel")
70 | self.setFixedWidth(640)
71 | self.setFixedHeight(480)
72 |
73 | # 로컬파일 사용시 절대경로만 사용해야 함
74 | url = QDir().current().filePath(
75 | "html/QWebEngineView_02_WebChannel.html")
76 | url = QUrl.fromLocalFile(url)
77 | self.web.load(url)
78 |
79 | # 핸들러 시그널 버튼이 눌러지면 console로 Hi를 보낸다.
80 | self.pb_1.clicked.connect(
81 | lambda v: self.handler.getText.emit(self.te_1.toPlainText()))
82 |
83 | self.layout_2.addWidget(self.web)
84 | self.layout_3.addWidget(self.pb_1)
85 | self.layout_3.addWidget(self.te_1)
86 |
87 |
88 | if __name__ == "__main__":
89 | sys.argv.append("--remote-debugging-port=8000")
90 | app = QApplication(sys.argv)
91 | form = Form()
92 | form.show()
93 | exit(app.exec_())
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/ItemViews_model_based/ItemViews_QListView_03_user_list_model.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding: utf-8
3 |
4 | # 예제 내용
5 | # * QListView 기본 사용법
6 | # * QAbstractListModel 을 이용한 사용자 모델 생성
7 | # * 리스트에 아이콘 넣기
8 |
9 | import sys
10 |
11 | from PyQt5.QtWidgets import QWidget
12 | from PyQt5.QtWidgets import QListView
13 | from PyQt5.QtCore import QAbstractListModel
14 | from PyQt5.QtWidgets import QAbstractItemView
15 | from PyQt5.QtCore import QVariant
16 | from PyQt5.QtWidgets import QApplication
17 | from PyQt5.QtCore import Qt
18 | from PyQt5.QtGui import QPixmap
19 |
20 | __author__ = "Deokyu Lim "
21 |
22 |
23 | class UserModel(QAbstractListModel):
24 | """
25 | ListModel은 두 가지의 필수 메소드를 작성해야 한다.
26 | int rowCount(self, parent=None, *args, **kwargs)
27 | QVariant data(self, QModelIndex, role=None)
28 | """
29 | def __init__(self, data=None, parent=None):
30 | QAbstractListModel.__init__(self, parent)
31 | self._data = data
32 |
33 | def rowCount(self, parent=None, *args, **kwargs):
34 | """
35 | 데이터의 개 수를 반환
36 | """
37 | return len(self._data)
38 |
39 | def data(self, QModelIndex, role=None):
40 | """
41 | 어떠한 이벤트가 일어났을 때 View가 Model.data를 호출
42 | View의 요구를 role을 참고하여 해당하는 값을 반환
43 | 해당하는 role에 대한 대응이 없을 경우 QVariant를 반환
44 | """
45 | item = self._data[QModelIndex.row()]
46 |
47 | if role == Qt.DisplayRole: # 값 출력시
48 | return "%s" % item['name']
49 | elif role == Qt.DecorationRole:
50 | return QPixmap(item['icon']).scaledToHeight(20)
51 | return QVariant()
52 |
53 | def flags(self, QModelIndex):
54 | """
55 | 모델 아이템별에 대한 정책
56 | """
57 | return Qt.ItemIsEditable | Qt.ItemIsSelectable | Qt.ItemIsEnabled | Qt.ItemIsTristate
58 |
59 | def setData(self, QModelIndex, value, role=None):
60 | """
61 | 값 수정시 호출
62 | """
63 | self._data[QModelIndex.row()]['name'] = value
64 | return True
65 |
66 |
67 | class Form(QWidget):
68 | def __init__(self):
69 | QWidget.__init__(self, flags=Qt.Widget)
70 | self.setWindowTitle("ItemView QListView")
71 | self.setFixedWidth(210)
72 | self.setFixedHeight(100)
73 |
74 | fruits = [
75 | {"name": "Mail", "icon": "assets/mail.png"},
76 | {"name": "Calender", "icon": "assets/calender.png"},
77 | {"name": "Network", "icon": "assets/network.png"},
78 | ]
79 |
80 | view = QListView(self)
81 | view.setAlternatingRowColors(True)
82 | view.setEditTriggers(QAbstractItemView.DoubleClicked)
83 |
84 | model = UserModel(fruits)
85 | view.setModel(model)
86 |
87 |
88 | if __name__ == "__main__":
89 | app = QApplication(sys.argv)
90 | form = Form()
91 | form.show()
92 | exit(app.exec_())
93 |
--------------------------------------------------------------------------------
/QtFramework/QtGui/QPixmap/QPixmap_05_select_box.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding: utf-8
3 |
4 | # 예제 내용
5 | # * QPixmap사용
6 |
7 | import sys
8 | from PyQt5.QtWidgets import QWidget
9 | from PyQt5.QtWidgets import QLabel
10 | from PyQt5.QtWidgets import QBoxLayout
11 | from PyQt5.QtWidgets import QApplication
12 | from PyQt5.QtGui import QPixmap
13 | from PyQt5.QtGui import QMouseEvent
14 | from PyQt5.QtCore import QRect
15 | from PyQt5.QtCore import pyqtSignal
16 | from PyQt5.QtCore import pyqtSlot
17 | from PyQt5.QtCore import QPoint
18 | from PyQt5.QtWidgets import QGraphicsOpacityEffect
19 |
20 |
21 | __author__ = "Deokyu Lim "
22 |
23 |
24 | class Rectangle(QLabel):
25 | change_position = pyqtSignal(QRect, name="changePosition")
26 |
27 | def __init__(self, parent=None):
28 | QLabel.__init__(self, parent)
29 | self.is_pressed = False
30 |
31 | def mousePressEvent(self, event: QMouseEvent):
32 | self.grab_location = event.pos()
33 | QWidget.mousePressEvent(self, event)
34 |
35 | def mouseMoveEvent(self, event: QMouseEvent):
36 | pos = event.pos()
37 | pos = self.pos() + pos
38 | self.move(pos - self.grab_location)
39 | self.change_position.emit(QRect(self.geometry()))
40 | QWidget.mouseMoveEvent(self, event)
41 |
42 | def mouseReleaseEvent(self, event: QMouseEvent):
43 | QWidget.mouseReleaseEvent(self, event)
44 |
45 |
46 | class Window(QWidget):
47 | def __init__(self):
48 | QWidget.__init__(self)
49 | self.origin_pixmap = QPixmap("apple.jpg")
50 | self.init_ui()
51 |
52 | def init_ui(self):
53 | self.setMinimumWidth(320)
54 | self.setMinimumHeight(240)
55 | layout = QBoxLayout(QBoxLayout.LeftToRight)
56 | self.setLayout(layout)
57 |
58 | lb_1 = QLabel()
59 | self.origin_pixmap = self.origin_pixmap.scaledToHeight(240) # 사이즈가 조정
60 | lb_1.setPixmap(self.origin_pixmap)
61 | layout.addWidget(lb_1)
62 |
63 | # 자를 영역 선택, 복사
64 | rect = QRect(50, 50, 50, 50)
65 | cropped = self.origin_pixmap.copy(rect)
66 |
67 | self.lb_2 = QLabel()
68 | self.lb_2.setPixmap(cropped)
69 | self.lb_2.setFixedSize(100, 100)
70 | layout.addWidget(self.lb_2)
71 |
72 | w = Rectangle(parent=lb_1)
73 | w.setGeometry(0, 0, 100, 100)
74 | w.setStyleSheet("background-color: red")
75 | opacity_effect = QGraphicsOpacityEffect(self)
76 | opacity_effect.setOpacity(0.3)
77 | w.setGraphicsEffect(opacity_effect)
78 |
79 | w.change_position.connect(self.crop_image)
80 |
81 | @pyqtSlot(QRect, name="cropImage")
82 | def crop_image(self, crop_rect):
83 | # 자를 영역 선택, 복사
84 | cropped = self.origin_pixmap.copy(crop_rect)
85 | self.lb_2.setPixmap(cropped)
86 |
87 |
88 | if __name__ == "__main__":
89 | app = QApplication(sys.argv)
90 | form = Window()
91 | form.show()
92 | exit(app.exec_())
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/QProgressBar/QProgressBar_01_thread.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding: utf-8
3 |
4 | # 예제 내용
5 | # * 실행상태바의 기본 사용
6 | # * Thread를 이용한 동시성
7 |
8 | import sys
9 |
10 | from PyQt5.QtWidgets import QWidget
11 | from PyQt5.QtWidgets import QProgressBar
12 | from PyQt5.QtWidgets import QPushButton
13 | from PyQt5.QtWidgets import QApplication
14 | from PyQt5.QtWidgets import QBoxLayout
15 | from PyQt5.QtCore import Qt
16 | from PyQt5.QtCore import QThread
17 | from PyQt5.QtCore import QWaitCondition
18 | from PyQt5.QtCore import QMutex
19 | from PyQt5.QtCore import pyqtSignal
20 | from PyQt5.QtCore import pyqtSlot
21 |
22 | __author__ = "Deokyu Lim "
23 |
24 |
25 | class Thread(QThread):
26 | """
27 | 단순히 0부터 100까지 카운트만 하는 쓰레드
28 | 값이 변경되면 그 값을 change_value 시그널에 값을 emit 한다.
29 | """
30 | # 사용자 정의 시그널 선언
31 | change_value = pyqtSignal(int)
32 |
33 | def __init__(self):
34 | QThread.__init__(self)
35 | self.cond = QWaitCondition()
36 | self.mutex = QMutex()
37 | self.cnt = 0
38 | self._status = True
39 |
40 | def __del__(self):
41 | self.wait()
42 |
43 | def run(self):
44 | while True:
45 | self.mutex.lock()
46 |
47 | if not self._status:
48 | self.cond.wait(self.mutex)
49 |
50 | if 100 == self.cnt:
51 | self.cnt = 0
52 | self.cnt += 1
53 | self.change_value.emit(self.cnt)
54 | self.msleep(100) # ※주의 QThread에서 제공하는 sleep을 사용
55 |
56 | self.mutex.unlock()
57 |
58 | def toggle_status(self):
59 | self._status = not self._status
60 | if self._status:
61 | self.cond.wakeAll()
62 |
63 | @property
64 | def status(self):
65 | return self._status
66 |
67 |
68 | class Form(QWidget):
69 | def __init__(self):
70 | QWidget.__init__(self, flags=Qt.Widget)
71 | self.pgsb = QProgressBar()
72 | self.pb = QPushButton("Pause")
73 | self.th = Thread()
74 | self.init_widget()
75 | self.th.start()
76 |
77 | def init_widget(self):
78 | self.setWindowTitle("QProgressBar with QThread")
79 | form_lbx = QBoxLayout(QBoxLayout.TopToBottom, parent=self)
80 | self.setLayout(form_lbx)
81 |
82 | # 시그널 슬롯 연결
83 | self.pb.clicked.connect(self.slot_clicked_button)
84 | self.th.change_value.connect(self.pgsb.setValue)
85 |
86 | form_lbx.addWidget(self.pgsb)
87 | form_lbx.addWidget(self.pb)
88 |
89 | @pyqtSlot()
90 | def slot_clicked_button(self):
91 | """
92 | 사용자정의 슬롯
93 | 쓰레드의 status 상태 변경
94 | 버튼 문자 변경
95 | 쓰레드 재시작
96 | """
97 | self.th.toggle_status()
98 | self.pb.setText({True: "Pause", False: "Resume"}[self.th.status])
99 |
100 |
101 | if __name__ == "__main__":
102 | app = QApplication(sys.argv)
103 | form = Form()
104 | form.show()
105 | exit(app.exec_())
--------------------------------------------------------------------------------
/QtFramework/QtGui/QPixmap/QPixmap_05_select_rubberband.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding: utf-8
3 |
4 | # 예제 내용
5 | # * QPixmap사용
6 |
7 | import sys
8 | from PyQt5.QtWidgets import QWidget
9 | from PyQt5.QtWidgets import QLabel
10 | from PyQt5.QtWidgets import QVBoxLayout
11 | from PyQt5.QtWidgets import QBoxLayout
12 | from PyQt5.QtWidgets import QSplitter
13 | from PyQt5.QtWidgets import QApplication
14 | from PyQt5.QtGui import QPixmap
15 | from PyQt5.QtGui import QMouseEvent
16 | from PyQt5.QtGui import QHoverEvent
17 | from PyQt5.QtWidgets import QSizeGrip
18 | from PyQt5.QtWidgets import QRubberBand
19 | from PyQt5.QtCore import QEvent
20 | from PyQt5.QtCore import QRect
21 | from PyQt5.QtCore import QSize
22 | from PyQt5.QtCore import pyqtSignal
23 | from PyQt5.QtCore import pyqtSlot
24 | from PyQt5.QtCore import Qt
25 |
26 | from PyQt5.QtWidgets import QGraphicsOpacityEffect
27 |
28 |
29 | __author__ = "Deokyu Lim "
30 |
31 |
32 | class Label(QLabel):
33 | selection_changed = pyqtSignal(QRect, name="selectionChanged")
34 |
35 | def __init__(self):
36 | QLabel.__init__(self)
37 | self.rb = QRubberBand(QRubberBand.Rectangle, self)
38 | self.setMouseTracking(True)
39 |
40 | def mousePressEvent(self, event: QMouseEvent):
41 | self.origin = event.pos()
42 | self.rb.setGeometry(QRect(self.origin, QSize()))
43 | self.rb.show()
44 | QLabel.mousePressEvent(self, event)
45 |
46 | def mouseMoveEvent(self, event: QMouseEvent):
47 | if self.rb.isVisible():
48 | self.rb.setGeometry(
49 | QRect(self.origin, event.pos()).normalized())
50 | QWidget.mouseMoveEvent(self, event)
51 |
52 | def mouseReleaseEvent(self, event):
53 | if self.rb.isVisible():
54 | self.rb.hide()
55 | self.selection_changed.emit(self.rb.geometry())
56 | QLabel.mouseReleaseEvent(self, event)
57 |
58 |
59 | class Window(QWidget):
60 | def __init__(self):
61 | QWidget.__init__(self)
62 | self.origin_pixmap = QPixmap("apple.jpg")
63 | self.init_ui()
64 |
65 | def init_ui(self):
66 | self.setMinimumWidth(320)
67 | self.setMinimumHeight(240)
68 | layout = QBoxLayout(QBoxLayout.LeftToRight)
69 | self.setLayout(layout)
70 |
71 | lb_1 = Label()
72 |
73 | self.origin_pixmap = self.origin_pixmap.scaledToHeight(240) # 사이즈가 조정
74 | lb_1.setPixmap(self.origin_pixmap)
75 | layout.addWidget(lb_1)
76 |
77 | # 자를 영역 선택, 복사
78 | rect = QRect(50, 50, 50, 50)
79 | cropped = self.origin_pixmap.copy(rect)
80 |
81 | self.lb_2 = QLabel()
82 | self.lb_2.setPixmap(cropped)
83 | self.lb_2.setFixedSize(100, 100)
84 | layout.addWidget(self.lb_2)
85 |
86 | lb_1.selection_changed.connect(self.crop_image)
87 |
88 | @pyqtSlot(QRect, name="cropImage")
89 | def crop_image(self, crop_rect):
90 | # 자를 영역 선택, 복사
91 | cropped = self.origin_pixmap.copy(crop_rect)
92 | self.lb_2.setPixmap(cropped)
93 |
94 |
95 | if __name__ == "__main__":
96 | app = QApplication(sys.argv)
97 | form = Window()
98 | form.show()
99 | exit(app.exec_())
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/QWidget/QWidget_02_Properties_PaintEvent.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding: utf-8
3 |
4 | # 예제 내용
5 | # * PaintEvent를 사용하여 실시간으로 값 변경하기
6 | # * MouseEvent를 사용하여 마우스 값 가져오기
7 |
8 | import sys
9 |
10 | from PyQt5.QtWidgets import QWidget
11 | from PyQt5.QtWidgets import QLabel
12 | from PyQt5.QtWidgets import QApplication
13 | from PyQt5.QtCore import Qt
14 |
15 | __author__ = "Deokyu Lim "
16 |
17 |
18 | class Form(QWidget):
19 | def __init__(self):
20 | QWidget.__init__(self, flags=Qt.Widget)
21 | # 마우스 좌표 저장용 변수
22 | self.mouse_x = 0
23 | self.mouse_y = 0
24 |
25 | self.lb = QLabel(self)
26 |
27 | self.properties_list = (
28 | "width", "height", "x", "y", "geometry",
29 | "maximumHeight", "maximumWidth", "maximumSize", "minimumSize", "minimumWidth",
30 | "size", "windowFilePath", "windowTitle",
31 | "underMouse"
32 | ) # 출력할 property 이름
33 |
34 | self.init_widget()
35 |
36 | def init_widget(self):
37 | self.setWindowTitle("Hello World")
38 | self.setGeometry(100, 100, 640, 480) # 창 위치, 크기 설정
39 | self.setMouseTracking(True) # 마우스 움직임을 캐치
40 |
41 | # QLabel 인스턴스 생성
42 | # 인자값으로 parent인 self 지정
43 | # QLabel(str, parent), QLabel(parent) 등으로 줄 수 있음
44 | self.lb.setStyleSheet("background-color: yellow") # 라벨위젯과의 구분을 위한 색
45 | self.lb.setMouseTracking(True) # False 값일 경우 Label 위젯에서는 mouse 이벤트가 발생하지 않는다.
46 | msg = self.get_properties_value(self.properties_list) # property 이름과 값을 돌려주는 함수 호출
47 | self.lb.setText(msg) # Label에 텍스트 설정
48 |
49 | def get_properties_value(self, properties):
50 | """
51 | 인자 값으로 property의 이름을 담은 시퀀스 자료형
52 | property를 차례로 호출하며 이름과 값의 문자열 생성
53 | :param properties list or tuple
54 | :return str
55 | """
56 | msg = []
57 | for p in properties:
58 | if not hasattr(self, p):
59 | continue
60 | value = getattr(self, p)() # == self.width(), self.x()
61 | msg.append("{:>20s} : {:<30s}".format(p, str(value)))
62 | msg.append("{:>20s} : {:<30s}".format("mouse_x", str(self.mouse_x)))
63 | msg.append("{:>20s} : {:<30s}".format("mouse_y", str(self.mouse_y)))
64 | msg = "\n".join(msg)
65 | return msg
66 |
67 | def mouseMoveEvent(self, QMouseEvent):
68 | """
69 | 위젯 안에서의 마우스 움직임이 일어날 때 호출
70 | :param QMouseEvent:
71 | :return:
72 | """
73 | self.mouse_x = QMouseEvent.x()
74 | self.mouse_y = QMouseEvent.y()
75 | self.update()
76 |
77 | def moveEvent(self, QMoveEvent):
78 | """
79 | 창이 이동했을 경우(이동 중 아님.) 호출
80 | :param QMoveEvent:
81 | :return:
82 | """
83 | self.update()
84 |
85 | def paintEvent(self, QPaintEvent):
86 | """
87 | 창을 다시 그려야 할 때 호출
88 | """
89 | msg = self.get_properties_value(self.properties_list)
90 | self.lb.setText(msg) # Label에 텍스트 설정
91 |
92 |
93 | if __name__ == "__main__":
94 | app = QApplication(sys.argv)
95 | form = Form()
96 | form.show()
97 | exit(app.exec_())
98 |
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/ItemWidget_Item_based/ItemWidget_QTreeWidget_06_move_to_other_widget.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding: utf-8
3 |
4 | # 예제 내용
5 | # * QTreeWidget을 사용하여 아이템을 표시
6 |
7 | __author__ = "Deokyu Lim "
8 |
9 | from PyQt5.QtWidgets import QWidget
10 | from PyQt5.QtWidgets import QTreeWidget
11 | from PyQt5.QtCore import QVariant
12 | from PyQt5.QtWidgets import QTreeWidgetItem
13 | from PyQt5.QtWidgets import QPushButton
14 | from PyQt5.QtWidgets import QBoxLayout
15 | from PyQt5.QtWidgets import QApplication
16 | from PyQt5.QtCore import Qt
17 |
18 |
19 | # 각 위젯의 모양과 배치를 맡는 부분과 실제 동작에 필요한 코드를 분리하였습니다.
20 | class UI(QWidget):
21 | HEADER = ["Name",]
22 |
23 | def __init__(self):
24 | QWidget.__init__(self, flags=Qt.Widget)
25 | self.setWindowTitle("QTreeWidget Column")
26 | self.setFixedWidth(300)
27 | self.setFixedHeight(300)
28 |
29 | # TreeWidget 1
30 | self.tw_1 = QTreeWidget(self)
31 | self.tw_1.setColumnCount(1)
32 | self.tw_1.setHeaderLabels(self.HEADER)
33 |
34 | # TreeWidget 1
35 | self.tw_2 = QTreeWidget(self)
36 | self.tw_2.setColumnCount(1)
37 | self.tw_2.setHeaderLabels(self.HEADER)
38 |
39 | # Buttons
40 | self.pb_move_left = QPushButton("<-")
41 | self.pb_move_right = QPushButton("->")
42 |
43 | layout = QBoxLayout(QBoxLayout.LeftToRight)
44 | layout.addWidget(self.tw_1)
45 | layout.addWidget(self.tw_2)
46 |
47 | main_layout = QBoxLayout(QBoxLayout.TopToBottom)
48 | main_layout.addLayout(layout)
49 | main_layout.addWidget(self.pb_move_right)
50 | main_layout.addWidget(self.pb_move_left)
51 |
52 | self.setLayout(main_layout)
53 |
54 |
55 | class Form(UI):
56 | def __init__(self):
57 | UI.__init__(self)
58 |
59 | # 데이터 초기화
60 | data = ["Apple", "Banana", "Tomato", "Cherry"]
61 | parent = QTreeWidget.invisibleRootItem(self.tw_1)
62 | for d in data:
63 | item = self.make_tree_item(d)
64 | parent.addChild(item)
65 |
66 | # 시그널 설정
67 | self.pb_move_right.clicked.connect(self.move_item)
68 | self.pb_move_left.clicked.connect(self.move_item)
69 |
70 | @classmethod
71 | def make_tree_item(cls, name: str):
72 | item = QTreeWidgetItem()
73 | item.setText(0, name)
74 | return item
75 |
76 | # 아이템 이동
77 | # sender를 이용하여 어느 위젯이 보낸 신호인지 알 수 있습니다.
78 | def move_item(self):
79 | sender = self.sender()
80 | if self.pb_move_right == sender:
81 | source_tw = self.tw_1
82 | target_tw = self.tw_2
83 | else:
84 | source_tw = self.tw_2
85 | target_tw = self.tw_1
86 |
87 | # 현재 선택된 아이템을 꺼내어 반대편 쪽으로 전달
88 | item = source_tw.takeTopLevelItem(source_tw.currentColumn())
89 | root = QTreeWidget.invisibleRootItem(target_tw)
90 | root.addChild(item)
91 |
92 |
93 |
94 |
95 | if __name__ == "__main__":
96 | import sys
97 | app = QApplication(sys.argv)
98 | form = Form()
99 | form.show()
100 | exit(app.exec_())
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/QWebEngineView/QWebEngineView_04_popup.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding: utf-8
3 |
4 | # 예제 내용
5 | # * QWebEngineView 새 창, 새 탭, 다이얼로그 창 생성 요구
6 |
7 | import sys
8 |
9 | from PyQt5.QtCore import QDir
10 | from PyQt5.QtCore import QUrl
11 | from PyQt5.QtWidgets import QApplication
12 | from PyQt5.QtWidgets import QWidget
13 |
14 | from PyQt5.QtWebEngineWidgets import QWebEngineView
15 | from PyQt5.QtWebEngineWidgets import QWebEngineSettings
16 | from PyQt5.QtWebEngineWidgets import QWebEnginePage
17 | from PyQt5.QtWebEngineWidgets import QWebEngineProfile
18 |
19 | from PyQt5.QtGui import QCloseEvent
20 |
21 | __author__ = "Deokyu Lim "
22 |
23 |
24 | class WebView(QWebEngineView):
25 | def __init__(self):
26 | QWebEngineView.__init__(self)
27 | self.settings().setAttribute(
28 | QWebEngineSettings.JavascriptCanOpenWindows, True)
29 | self.p = Page()
30 | self.setPage(self.p)
31 | self.settings().setAttribute(QWebEngineSettings.JavascriptEnabled, True)
32 | self.settings().setAttribute(QWebEngineSettings.JavascriptCanOpenWindows, True)
33 |
34 | def createWindow(self, wind_type):
35 | print(wind_type)
36 | # 새로운 탭 생성 요구시
37 | if wind_type == QWebEnginePage.WebBrowserTab:
38 | # 주의: 아래 코드는 새 윈도우를 만들어 주는 코드이다.
39 | # 본 예제는 탭을 사용하지 않으므로 새 창으로 대체
40 |
41 | # View 는 반드시 클래스 변수 생성로 해주어야 한다.
42 | # 로컬 변수로 생성시 메서드 리턴시 소멸
43 | # self.popup = WebPopupWindow(self.page().profile())
44 | self.popup = WebPopupWindow(self.p.profile())
45 | view = self.popup.view()
46 | self.popup.show()
47 | return view
48 | if wind_type == QWebEnginePage.WebBrowserBackgroundTab:
49 | pass
50 | # 새로운 창 생성 요구시
51 | if wind_type == QWebEnginePage.WebBrowserWindow:
52 | pass
53 | # 다이얼로그 창 생성 요구시
54 | if wind_type == QWebEnginePage.WebDialog:
55 | popup = Frame(self.page().profile())
56 | popup.show()
57 | return popup.web
58 | return None
59 |
60 |
61 | class Page(QWebEnginePage):
62 | pass
63 |
64 |
65 | class WebPopupWindow(WebView):
66 | def __init__(self, profile: QWebEngineProfile):
67 | WebView.__init__(self)
68 | page = Page(profile, self)
69 | # window.open 의 인수값으로 입력된 위치크기 정보를 이용하여 크기 변경
70 | # window.open에서 width, height, x, y 값이 인자 값으로 있다면 아래의
71 | # 코드가 반드시 필요
72 | page.geometryChangeRequested.connect(self.setGeometry)
73 |
74 | self.setPage(page)
75 | self.setFocus()
76 |
77 | def closeEvent(self, event: QCloseEvent):
78 | WebView.closeEvent(self, event)
79 |
80 |
81 | class Frame(QWidget):
82 | def __init__(self, profile):
83 | QWidget.__init__(self)
84 | self.web = WebPopupWindow(profile)
85 | self.web.show()
86 |
87 |
88 | if __name__ == "__main__":
89 | sys.argv.append("--remote-debugging-port=8000")
90 |
91 | app = QApplication(sys.argv)
92 | form = WebView()
93 | # 로컬파일 사용시 절대경로만 사용해야 함
94 | url = QDir().current().filePath(
95 | "html/QWebEngineView_04_popup.html")
96 | url = QUrl.fromLocalFile(url)
97 | form.setUrl(url)
98 | form.show()
99 | exit(app.exec_())
100 |
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/QLabel/QLabel_01_alignment.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding: utf-8
3 |
4 | # 예제 내용
5 | # * QLabel에 표현될 내용물의 위치를 결정
6 |
7 | import sys
8 | from PyQt5.QtWidgets import QWidget
9 | from PyQt5.QtWidgets import QLabel
10 | from PyQt5.QtWidgets import QGridLayout
11 | from PyQt5.QtWidgets import QApplication
12 | from PyQt5.QtGui import QPixmap
13 | from PyQt5.QtCore import Qt
14 |
15 | __author__ = "Deokyu Lim "
16 |
17 |
18 | class Window(QWidget):
19 | def __init__(self):
20 | QWidget.__init__(self)
21 |
22 | self.init_ui()
23 |
24 | def init_ui(self):
25 | layout = QGridLayout()
26 | self.setLayout(layout)
27 | pixmap = QPixmap("apple.jpg")
28 | pixmap = pixmap.scaledToHeight(25) # 사이즈가 조정
29 |
30 | # 라벨에 출력될 내용의 정렬을 선택한다.
31 | # 정렬 속성은 여러개를 사용할 수 있다.
32 |
33 | # 가운데 정렬
34 | lb = QLabel()
35 | lb.setFixedSize(100, 100)
36 | lb.setStyleSheet("background-color: gray")
37 | lb.setPixmap(pixmap)
38 | lb.setAlignment(Qt.AlignLeft | Qt.AlignTop)
39 | layout.addWidget(lb, 0, 0)
40 |
41 | # 라벨에 출력될 내용의 정렬을 선택한다.
42 | lb = QLabel()
43 | lb.setFixedSize(100, 100)
44 | lb.setStyleSheet("background-color: gray")
45 | lb.setPixmap(pixmap)
46 | lb.setAlignment(Qt.AlignHCenter | Qt.AlignTop)
47 | layout.addWidget(lb, 0, 1)
48 |
49 | lb = QLabel()
50 | lb.setFixedSize(100, 100)
51 | lb.setStyleSheet("background-color: gray")
52 | lb.setPixmap(pixmap)
53 | lb.setAlignment(Qt.AlignRight | Qt.AlignTop)
54 | layout.addWidget(lb, 0, 2)
55 |
56 | lb = QLabel()
57 | lb.setFixedSize(100, 100)
58 | lb.setStyleSheet("background-color: gray")
59 | lb.setPixmap(pixmap)
60 | lb.setAlignment(Qt.AlignLeft | Qt.AlignVCenter)
61 | layout.addWidget(lb, 1, 0)
62 |
63 | lb = QLabel()
64 | lb.setFixedSize(100, 100)
65 | lb.setStyleSheet("background-color: gray")
66 | lb.setPixmap(pixmap)
67 | lb.setAlignment(Qt.AlignCenter | Qt.AlignVCenter)
68 | layout.addWidget(lb, 1, 1)
69 |
70 | lb = QLabel()
71 | lb.setFixedSize(100, 100)
72 | lb.setStyleSheet("background-color: gray")
73 | lb.setPixmap(pixmap)
74 | lb.setAlignment(Qt.AlignRight | Qt.AlignVCenter)
75 | layout.addWidget(lb, 1, 2)
76 |
77 | lb = QLabel()
78 | lb.setFixedSize(100, 100)
79 | lb.setStyleSheet("background-color: gray")
80 | lb.setPixmap(pixmap)
81 | lb.setAlignment(Qt.AlignLeft | Qt.AlignBottom)
82 | layout.addWidget(lb, 2, 0)
83 |
84 | lb = QLabel()
85 | lb.setFixedSize(100, 100)
86 | lb.setStyleSheet("background-color: gray")
87 | lb.setPixmap(pixmap)
88 | lb.setAlignment(Qt.AlignHCenter | Qt.AlignBottom)
89 | layout.addWidget(lb, 2, 1)
90 |
91 | lb = QLabel()
92 | lb.setFixedSize(100, 100)
93 | lb.setStyleSheet("background-color: gray")
94 | lb.setPixmap(pixmap)
95 | lb.setAlignment(Qt.AlignRight | Qt.AlignBottom)
96 | layout.addWidget(lb, 2, 2)
97 |
98 |
99 | if __name__ == "__main__":
100 | app = QApplication(sys.argv)
101 | form = Window()
102 | form.show()
103 | exit(app.exec_())
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/QStackedWidget/QStackedWidget_00_basic.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding: utf-8
3 |
4 | # 예제 내용
5 | # * 스택 위젯의 기본 사용법
6 | # * 여러 위젯을 한 위젯 공간에 선택될 수 있도록 한다.
7 |
8 | import sys
9 |
10 | from PyQt5.QtWidgets import QWidget
11 | from PyQt5.QtWidgets import QStackedWidget
12 | from PyQt5.QtWidgets import QTextEdit
13 | from PyQt5.QtWidgets import QPushButton
14 | from PyQt5.QtWidgets import QLabel
15 | from PyQt5.QtWidgets import QGroupBox
16 | from PyQt5.QtWidgets import QListView
17 | from PyQt5.QtGui import QStandardItem
18 | from PyQt5.QtGui import QStandardItemModel
19 | from PyQt5.QtCore import QModelIndex
20 |
21 | from PyQt5.QtWidgets import QBoxLayout
22 | from PyQt5.QtWidgets import QApplication
23 | from PyQt5.QtCore import Qt
24 | from PyQt5.QtCore import pyqtSlot
25 |
26 |
27 | __author__ = "Deokyu Lim "
28 |
29 |
30 | class StWidgetForm(QGroupBox):
31 | """
32 | 위젯 베이스 클래스
33 | """
34 | def __init__(self):
35 | QGroupBox.__init__(self)
36 | self.box = QBoxLayout(QBoxLayout.TopToBottom)
37 | self.setLayout(self.box)
38 |
39 |
40 | class Widget_1(StWidgetForm):
41 | """
42 | 버튼 그룹
43 | """
44 | def __init__(self):
45 | super(Widget_1, self).__init__()
46 | self.setTitle("Widget_1")
47 | self.box.addWidget(QPushButton("Test_1"))
48 | self.box.addWidget(QPushButton("Test_2"))
49 | self.box.addWidget(QPushButton("Test_3"))
50 |
51 |
52 | class Widget_2(StWidgetForm):
53 | def __init__(self):
54 | super(Widget_2, self).__init__()
55 | self.setTitle("Widget_2")
56 | self.box.addWidget(QTextEdit())
57 |
58 |
59 | class Widget_3(StWidgetForm):
60 | def __init__(self):
61 | super(Widget_3, self).__init__()
62 | self.setTitle("Widget_3")
63 | self.box.addWidget(QLabel("Test Label"))
64 |
65 |
66 | class Form(QWidget):
67 | def __init__(self):
68 | QWidget.__init__(self, flags=Qt.Widget)
69 | self.stk_w = QStackedWidget(self)
70 | self.init_widget()
71 |
72 | def init_widget(self):
73 | self.setWindowTitle("Hello World")
74 | widget_laytout = QBoxLayout(QBoxLayout.LeftToRight)
75 |
76 | group = QGroupBox()
77 | box = QBoxLayout(QBoxLayout.TopToBottom)
78 | group.setLayout(box)
79 | group.setTitle("Buttons")
80 | widget_laytout.addWidget(group)
81 |
82 | fruits = ["Buttons in GroupBox", "TextBox in GroupBox", "Label in GroupBox", "TextEdit"]
83 | view = QListView(self)
84 | model = QStandardItemModel()
85 | for f in fruits:
86 | model.appendRow(QStandardItem(f))
87 | view.setModel(model)
88 | box.addWidget(view)
89 |
90 | self.stk_w.addWidget(Widget_1())
91 | self.stk_w.addWidget(Widget_2())
92 | self.stk_w.addWidget(Widget_3())
93 | self.stk_w.addWidget(QTextEdit())
94 |
95 | widget_laytout.addWidget(self.stk_w)
96 | self.setLayout(widget_laytout)
97 |
98 | # 시그널 슬롯 연결
99 | view.clicked.connect(self.slot_clicked_item)
100 |
101 | @pyqtSlot(QModelIndex)
102 | def slot_clicked_item(self, QModelIndex):
103 | self.stk_w.setCurrentIndex(QModelIndex.row())
104 |
105 |
106 |
107 |
108 | if __name__ == "__main__":
109 | app = QApplication(sys.argv)
110 | form = Form()
111 | form.show()
112 | exit(app.exec_())
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/QWebEngineView/QWebEngineView_07_print_request.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding: utf-8
3 |
4 | # 예제 내용
5 | # * QWebEngineView 새 창, 새 탭, 다이얼로그 창 생성 요구
6 |
7 | import sys
8 | from PyQt5.QtWidgets import QApplication
9 | from PyQt5.QtCore import QDir
10 | from PyQt5.QtCore import QFile
11 | from PyQt5.QtCore import QObject
12 | from PyQt5.QtWebEngineWidgets import QWebEngineView
13 | from PyQt5.QtWebEngineWidgets import QWebEngineScript
14 | from PyQt5.QtCore import QUrl
15 | from PyQt5.QtCore import pyqtSignal
16 | from PyQt5.QtCore import pyqtSlot
17 | from PyQt5.QtPrintSupport import QPrintDialog
18 |
19 | import qwebchannel_rc
20 |
21 | from PyQt5.QtWebChannel import QWebChannel
22 |
23 | __author__ = "Deokyu Lim "
24 |
25 |
26 | class CallHandler(QObject):
27 | request_print = pyqtSignal(name="requestPrint")
28 |
29 | def __init__(self, parent=None):
30 | QObject.__init__(self, parent)
31 |
32 | @pyqtSlot(name="webToAppRequestPrint")
33 | def web_to_app_request_print(self):
34 | self.request_print.emit()
35 |
36 |
37 | class WebView(QWebEngineView):
38 | def __init__(self):
39 | QWebEngineView.__init__(self)
40 | url = QDir().current().filePath(
41 | "html/QWebEngineView_07_print_request.html")
42 | url = QUrl.fromLocalFile(url)
43 | self.setUrl(url)
44 | web_channel_js = QWebEngineScript()
45 | web_channel_js.setInjectionPoint(QWebEngineScript.DocumentCreation)
46 | web_channel_js.setWorldId(QWebEngineScript.MainWorld)
47 | web_channel_js.setRunsOnSubFrames(True)
48 | web_channel_js_file = QFile(":/qwebchannel")
49 | web_channel_js_file.open(QFile.ReadOnly)
50 | js = str(web_channel_js_file.readAll(), 'utf-8')
51 | web_channel_js.setSourceCode(js)
52 | self.page().scripts().insert(web_channel_js)
53 |
54 | # Javascript window.print()를 오버라이드
55 | # 기본 window.print()는 웹브라우져에게 프린터 다이얼로그를 요청하지만
56 | # 받을 수 없기 때문에 QWebChannel을 통해 받는다.
57 | override_js_print = QWebEngineScript()
58 | override_js_print.setInjectionPoint(QWebEngineScript.DocumentCreation)
59 | override_js_print.setWorldId(QWebEngineScript.MainWorld)
60 | override_js_print.setName("oveerridejsprint.js")
61 | override_js_print.setRunsOnSubFrames(True)
62 | override_js_print.setSourceCode(
63 | "window.print = function() { "
64 | " new QWebChannel(qt.webChannelTransport, function(channel) { "
65 | " handler = channel.objects.handler; "
66 | " handler.webToAppRequestPrint(); "
67 | " });"
68 | "};"
69 | )
70 | self.page().scripts().insert(override_js_print)
71 | channel = QWebChannel(self.page())
72 | self.page().setWebChannel(channel)
73 | self.handler = CallHandler()
74 | channel.registerObject('handler', self.handler)
75 |
76 | # 시그널슬롯 처리
77 | self.handler.request_print.connect(self.printer)
78 |
79 | # 프린트 다이얼로그 처리
80 | def printer(self):
81 | prnt_dialog = QPrintDialog(self)
82 | if not prnt_dialog.exec():
83 | prnt_dialog.deleteLater()
84 | return
85 | self.page().print(
86 | prnt_dialog.printer(), lambda status: prnt_dialog.deleteLater())
87 |
88 |
89 | if __name__ == "__main__":
90 | sys.argv.append("--remote-debugging-port=8000")
91 |
92 | app = QApplication(sys.argv)
93 | form = WebView()
94 | form.show()
95 | exit(app.exec_())
96 |
--------------------------------------------------------------------------------
/QtFramework/QtWidgets/ItemViews_model_based/ItemViews_QTreeView_03_style.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # coding: utf-8
3 |
4 | # 예제 내용
5 | # * QListView 기본 사용법
6 | # * QAbstractListModel 을 이용한 사용자 모델 생성
7 | # * 모양 다듬기
8 |
9 | import sys
10 |
11 | from PyQt5.QtWidgets import QWidget
12 | from PyQt5.QtWidgets import QLabel
13 | from PyQt5.QtWidgets import QTreeView
14 | from PyQt5.QtCore import QVariant
15 | from PyQt5.QtGui import QStandardItemModel
16 | from PyQt5.QtGui import QStandardItem
17 | from PyQt5.QtGui import QPixmap
18 | from PyQt5.QtWidgets import QApplication
19 | from PyQt5.QtCore import Qt
20 | from PyQt5.QtWidgets import QBoxLayout
21 |
22 | __author__ = "Deokyu Lim "
23 |
24 |
25 | class Model(QStandardItemModel):
26 | """
27 | 사용자 데이터 모델 설정
28 |
29 | """
30 | def __init__(self, data):
31 | """
32 | :param data = [{"type":str, "objects":[str, ...]}, "picture":str, ...]
33 | """
34 | QStandardItemModel.__init__(self)
35 |
36 | # QStandardItem에 데이터를 넣고 model에 추가
37 | root = self.invisibleRootItem()
38 | root.appendRows(self.recursive_data_set(data))
39 | self.setItemPrototype(root)
40 |
41 | def recursive_data_set(self, data):
42 | items = list()
43 | for d in data:
44 | item = QStandardItem(d["name"])
45 | item.setData(d["icon"], Qt.DecorationRole)
46 | if d['objects']:
47 | item.appendRows(self.recursive_data_set(d['objects']))
48 | items.append(item)
49 | return items
50 |
51 | def data(self, QModelIndex, role=None):
52 | data = self.itemData(QModelIndex)
53 | if role == Qt.DisplayRole:
54 | ret = data[role]
55 | elif role in data and role == Qt.DecorationRole:
56 | ret = QPixmap(data[role]).scaledToHeight(25)
57 | else:
58 | ret = QVariant()
59 | return ret
60 |
61 |
62 | class Form(QWidget):
63 | def __init__(self):
64 | QWidget.__init__(self, flags=Qt.Widget)
65 | self.setWindowTitle("ItemView QTreeView")
66 | self.setFixedWidth(310)
67 | self.setFixedHeight(200)
68 |
69 | data = [
70 | {"name": "Mouse Action", "icon": "assets/mouse.png", "objects": [
71 | {"name": "Click", "icon": "assets/network.png", "objects": None},
72 | {"name": "Double Click", "icon": "assets/mail.png", "objects": None},
73 | ]},
74 | {"name": "Keyboard", "icon": "assets/keyboard.png", "objects": [
75 | {"name": "Send Hotkey", "icon": "assets/earth.png", "objects": None},
76 | {"name": "Type", "icon": "assets/folder.png", "objects": None},
77 | ]}
78 | ]
79 |
80 | self.layout = QBoxLayout(QBoxLayout.LeftToRight, self)
81 | self.setLayout(self.layout)
82 |
83 | # QTreeView 생성 및 설정
84 | view = QTreeView(self)
85 | # QTreeView 스타일시트 설정
86 | view.setStyleSheet(open("./ItemViews_QTreeView_03_style.css").read())
87 | view.setAlternatingRowColors(True) # 라인별 교차색
88 | self.model = Model(data)
89 | view.setModel(self.model)
90 | self.layout.addWidget(view)
91 |
92 | # 그림을 띄울 QLabel 생성
93 | self.lb = QLabel()
94 | self.lb.setFixedSize(50, 50)
95 | self.layout.addWidget(self.lb)
96 |
97 |
98 | if __name__ == "__main__":
99 | app = QApplication(sys.argv)
100 | form = Form()
101 | form.show()
102 | exit(app.exec_())
103 |
--------------------------------------------------------------------------------