├── .gitignore ├── 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 ├── DataPort │ └── serial_controler.py ├── NotePad │ ├── __init__.py │ ├── notepad.ico │ ├── notepad.py │ ├── notepad_i18n.pro │ ├── notepad_menubar.py │ ├── notepad_statusbar.py │ ├── notepad_texteditor.py │ └── translate │ │ ├── ko_KR.qm │ │ └── ko_KR.ts ├── README.md └── SceenCapture │ ├── __init__.py │ ├── v0 │ ├── __init__.py │ └── capture.py │ ├── v1 │ ├── __init__.py │ └── capture.py │ └── v2 │ ├── __init__.py │ └── capture.py ├── QnA_Examples └── input_tab_result_tab │ └── input_tab_result_tab.py ├── QtFramework ├── QML │ ├── 05-PyQt_QML_simple_examples │ │ └── 10-PyQt_QML_simple_example.qml │ ├── 10-PyQt_QML_basic │ │ ├── 10-PyQt_QML_basic.py │ │ ├── 10-PyQt_QML_basic.qml │ │ ├── 11-PyQt_QML_javascript_in_QML.py │ │ └── 11-PyQt_QML_javascript_in_QML.qml │ └── 20-Layout │ │ ├── 10-PyQt_QML_layout.qml │ │ └── 10-PyQt_QML_layout.qml.autosave ├── Qt │ ├── Internationalization │ │ ├── i18n_01 │ │ │ ├── i18n.pro │ │ │ └── i18n_01.py │ │ └── i18n_02 │ │ │ ├── en_US.ts │ │ │ ├── i18n.pro │ │ │ └── i18n_02.py │ └── README.md ├── QtCore │ └── QDomDocument │ │ └── QDomDocument_00_basic.py ├── QtGui │ └── QPixmap │ │ ├── QPixmap_00_basic.py │ │ ├── QPixmap_02_render.py │ │ ├── QPixmap_03_base64.py │ │ ├── QPixmap_04_image_to_base64.py │ │ ├── QPixmap_05_crop.py │ │ ├── QPixmap_05_select_box.py │ │ ├── QPixmap_05_select_rubberband.py │ │ └── apple.jpg ├── QtWidgets │ ├── Buttons │ │ ├── Buttons_QCheckBox_00_basic.py │ │ ├── Buttons_QCheckBox_01_change_state.py │ │ ├── Buttons_QPushButton_00_basic.py │ │ ├── Buttons_QPushButton_02_toggle.py │ │ ├── Buttons_QPushButton_03_Pressed_Released_event.py │ │ ├── Buttons_QPushButton_04_shortcut.py │ │ ├── Buttons_QPushButton_05_auto_repeat.py │ │ ├── Buttons_QRadioButton_00_basic.py │ │ └── Buttons_QRadioButton_01_buttons_in_group.py │ ├── Drag_and_Drop │ │ ├── drag_and_drop_00_basic.py │ │ ├── drag_and_drop_01_move_button.py │ │ └── drag_and_drop_02_keep_feature.py │ ├── GroupBox │ │ └── QGroupBox_00_basic.py │ ├── ItemViews_model_based │ │ ├── ItemViews_QListView_00_basic.py │ │ ├── ItemViews_QListView_01_user_list_model.py │ │ ├── ItemViews_QListView_02_user_list_model.py │ │ ├── ItemViews_QListView_03_user_list_model.py │ │ ├── ItemViews_QTreeView_00_basic.py │ │ ├── ItemViews_QTreeView_01_pixmap.py │ │ ├── ItemViews_QTreeView_02_signal_slot.py │ │ ├── ItemViews_QTreeView_03_style.css │ │ ├── ItemViews_QTreeView_03_style.py │ │ ├── ItemViews_QTreeView_04_header.py │ │ ├── ItemViews_QTreeView_05_header.py │ │ ├── ItemViews_QTreeView_06_delegate.py │ │ ├── ItemViews_QTreeView_07_TreeModel.py │ │ ├── ItemViews_QTreeView_08_TreeModel_property_grid.py │ │ ├── assets │ │ │ ├── calender.png │ │ │ ├── earth.png │ │ │ ├── folder.png │ │ │ ├── keyboard.png │ │ │ ├── mail.png │ │ │ ├── mouse.png │ │ │ └── network.png │ │ ├── shield.png │ │ └── sword.png │ ├── ItemWidget_Item_based │ │ ├── ItemWidget_QListWidget_00_basic.py │ │ ├── ItemWidget_QListWidget_01_widget_item.py │ │ ├── ItemWidget_QTreeWidget_00_basic.py │ │ ├── ItemWidget_QTreeWidget_00_basic_2.py │ │ ├── ItemWidget_QTreeWidget_01_column.py │ │ ├── ItemWidget_QTreeWidget_02_header.py │ │ ├── ItemWidget_QTreeWidget_03_widget.py │ │ ├── ItemWidget_QTreeWidget_04_properties_editor.py │ │ ├── ItemWidget_QTreeWidget_05_properties_editor_trees.py │ │ ├── ItemWidget_QTreeWidget_06_move_to_other_widget.py │ │ └── ex.json │ ├── QComboBox │ │ ├── QComboBox_00_basic.py │ │ ├── QComboBox_01_model.py │ │ ├── QComboBox_02_model_decoration.py │ │ └── QComboBox_03_model_tableview.py │ ├── QDockWidget │ │ └── QDockWidget_00_basic.py │ ├── QFileDialLog │ │ ├── QFileDialLog_00_basic.py │ │ └── QFileDialLog_01_initial_display.py │ ├── QLabel │ │ └── QLabel_01_alignment.py │ ├── QLayout │ │ ├── QLayout_00_Basic.py │ │ ├── QLayout_01_Basic.py │ │ ├── QLayout_02_complex_layout.py │ │ └── QLayout_03_complex_layout.py │ ├── QLineEdit │ │ ├── QLineEdit_00_basic.py │ │ ├── QLineEdit_01_input_mask.py │ │ └── QLineEdit_02_completer.py │ ├── QProgressBar │ │ ├── QProgressBar_00_basic.py │ │ └── QProgressBar_01_thread.py │ ├── QSplitter │ │ ├── QSplitter_00_basic.py │ │ └── QSplitter_01_tab_split.py │ ├── QStackedWidget │ │ └── QStackedWidget_00_basic.py │ ├── QTabWidget │ │ ├── QTabWidget_00_basic.py │ │ ├── QTabWidget_01_add_tab.py │ │ ├── QTabWidget_02_add_widget_in_tab.py │ │ └── plus_icon.png │ ├── QTextEdit │ │ ├── QTextEdit_00_basic.py │ │ └── QTextEdit_01_TextCursor.py │ ├── QToolBar │ │ ├── QToolBar_00_basic.py │ │ ├── QToolBar_01_sub_menu.py │ │ └── assets │ │ │ ├── icon_split_horizontal.svg │ │ │ └── icon_split_vertical.svg │ ├── QWebEngineView │ │ ├── QWebEngineView_00_basic.py │ │ ├── QWebEngineView_01_simple_web_browser.py │ │ ├── QWebEngineView_02_WebChannel.py │ │ ├── QWebEngineView_03_simple_web_browser.py │ │ ├── QWebEngineView_04_popup.py │ │ ├── QWebEngineView_05_DownloadRequest.py │ │ ├── QWebEngineView_06_close_request.py │ │ ├── QWebEngineView_07_print_request.py │ │ ├── QWebEngineView_08_alert.py │ │ ├── QWebEngineView_09_WebChannelDataType.py │ │ ├── QWebEngineView_10_plugin_enabled.py │ │ ├── html │ │ │ ├── QWebEngineView_02_WebChannel.html │ │ │ ├── QWebEngineView_04_popup.html │ │ │ ├── QWebEngineView_05_download_request.html │ │ │ ├── QWebEngineView_06_close_request.html │ │ │ ├── QWebEngineView_07_print_request.html │ │ │ ├── QWebEngineView_08_alert.html │ │ │ ├── QWebEngineView_09_WebChannelDataType.html │ │ │ ├── QWebEngineView_10_plugin_enabled.html │ │ │ └── snow.swf │ │ ├── images │ │ │ ├── go-next.png │ │ │ ├── go-previous.png │ │ │ ├── process-stop.png │ │ │ ├── view-dom_tree.png │ │ │ └── view-refresh.png │ │ ├── js │ │ │ ├── QWebEngineView_02_WebChannel.js │ │ │ ├── QWebEngineView_09_WebChannelDataType.js │ │ │ └── qwebchannel.js │ │ ├── qwebchannel.qrc │ │ └── qwebchannel_rc.py │ ├── QWidget │ │ ├── QWidget_00_Form.py │ │ ├── QWidget_01_Properties.py │ │ ├── QWidget_02_Properties_PaintEvent.py │ │ ├── QWidget_03_ChangeBackgroundColor.py │ │ ├── QWidget_06_Change_Icon.py │ │ ├── QWidget_08_mouse_tracker.py │ │ ├── QWidget_Find_Child_Widget.py │ │ ├── QWidget_enter_leave_evnet.py │ │ ├── QWidget_opacity.py │ │ ├── QWidget_stack_high_lower.py │ │ ├── README.md │ │ ├── shield.png │ │ └── sword.png │ ├── QWizard │ │ ├── QWizard_00_basic.py │ │ ├── QWizard_01_is_completed.py │ │ └── QWizard_02_is_completed.py │ └── Signal_Slot │ │ ├── signal_slot_00_basic.py │ │ ├── signal_slot_01_lambda.py │ │ ├── signal_slot_02_custom_signal.py │ │ ├── signal_slot_03_custom_signal.py │ │ ├── signal_slot_04_custom_slot.py │ │ ├── signal_slot_05_custom_slot.py │ │ └── signal_slot_06_custom_slot.py └── README.md └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /Projects/NotePad/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RavenKyu/OpenTutorials_PyQt/1fff4b33fe286377f1263e265480dda9026fe65f/Projects/NotePad/__init__.py -------------------------------------------------------------------------------- /Projects/NotePad/notepad.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RavenKyu/OpenTutorials_PyQt/1fff4b33fe286377f1263e265480dda9026fe65f/Projects/NotePad/notepad.ico -------------------------------------------------------------------------------- /Projects/NotePad/notepad_i18n.pro: -------------------------------------------------------------------------------- 1 | SOURCES += notepad.py notepad_menubar.py 2 | TRANSLATIONS += translate/ko_KR.ts -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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_()) -------------------------------------------------------------------------------- /Projects/NotePad/translate/ko_KR.qm: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RavenKyu/OpenTutorials_PyQt/1fff4b33fe286377f1263e265480dda9026fe65f/Projects/NotePad/translate/ko_KR.qm -------------------------------------------------------------------------------- /Projects/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RavenKyu/OpenTutorials_PyQt/1fff4b33fe286377f1263e265480dda9026fe65f/Projects/README.md -------------------------------------------------------------------------------- /Projects/SceenCapture/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RavenKyu/OpenTutorials_PyQt/1fff4b33fe286377f1263e265480dda9026fe65f/Projects/SceenCapture/__init__.py -------------------------------------------------------------------------------- /Projects/SceenCapture/v0/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RavenKyu/OpenTutorials_PyQt/1fff4b33fe286377f1263e265480dda9026fe65f/Projects/SceenCapture/v0/__init__.py -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /Projects/SceenCapture/v1/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RavenKyu/OpenTutorials_PyQt/1fff4b33fe286377f1263e265480dda9026fe65f/Projects/SceenCapture/v1/__init__.py -------------------------------------------------------------------------------- /Projects/SceenCapture/v2/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RavenKyu/OpenTutorials_PyQt/1fff4b33fe286377f1263e265480dda9026fe65f/Projects/SceenCapture/v2/__init__.py -------------------------------------------------------------------------------- /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/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/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 | -------------------------------------------------------------------------------- /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_()) -------------------------------------------------------------------------------- /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/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/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.pro: -------------------------------------------------------------------------------- 1 | SOURCES += i18n_01.py 2 | TRANSLATIONS += translate/ko_KR.ts -------------------------------------------------------------------------------- /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/Qt/Internationalization/i18n_02/en_US.ts: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /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/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/Qt/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RavenKyu/OpenTutorials_PyQt/1fff4b33fe286377f1263e265480dda9026fe65f/QtFramework/Qt/README.md -------------------------------------------------------------------------------- /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/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/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/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/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/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/QtGui/QPixmap/apple.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RavenKyu/OpenTutorials_PyQt/1fff4b33fe286377f1263e265480dda9026fe65f/QtFramework/QtGui/QPixmap/apple.jpg -------------------------------------------------------------------------------- /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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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 | -------------------------------------------------------------------------------- /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/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/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/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/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_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/ItemViews_model_based/assets/calender.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RavenKyu/OpenTutorials_PyQt/1fff4b33fe286377f1263e265480dda9026fe65f/QtFramework/QtWidgets/ItemViews_model_based/assets/calender.png -------------------------------------------------------------------------------- /QtFramework/QtWidgets/ItemViews_model_based/assets/earth.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RavenKyu/OpenTutorials_PyQt/1fff4b33fe286377f1263e265480dda9026fe65f/QtFramework/QtWidgets/ItemViews_model_based/assets/earth.png -------------------------------------------------------------------------------- /QtFramework/QtWidgets/ItemViews_model_based/assets/folder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RavenKyu/OpenTutorials_PyQt/1fff4b33fe286377f1263e265480dda9026fe65f/QtFramework/QtWidgets/ItemViews_model_based/assets/folder.png -------------------------------------------------------------------------------- /QtFramework/QtWidgets/ItemViews_model_based/assets/keyboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RavenKyu/OpenTutorials_PyQt/1fff4b33fe286377f1263e265480dda9026fe65f/QtFramework/QtWidgets/ItemViews_model_based/assets/keyboard.png -------------------------------------------------------------------------------- /QtFramework/QtWidgets/ItemViews_model_based/assets/mail.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RavenKyu/OpenTutorials_PyQt/1fff4b33fe286377f1263e265480dda9026fe65f/QtFramework/QtWidgets/ItemViews_model_based/assets/mail.png -------------------------------------------------------------------------------- /QtFramework/QtWidgets/ItemViews_model_based/assets/mouse.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RavenKyu/OpenTutorials_PyQt/1fff4b33fe286377f1263e265480dda9026fe65f/QtFramework/QtWidgets/ItemViews_model_based/assets/mouse.png -------------------------------------------------------------------------------- /QtFramework/QtWidgets/ItemViews_model_based/assets/network.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RavenKyu/OpenTutorials_PyQt/1fff4b33fe286377f1263e265480dda9026fe65f/QtFramework/QtWidgets/ItemViews_model_based/assets/network.png -------------------------------------------------------------------------------- /QtFramework/QtWidgets/ItemViews_model_based/shield.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RavenKyu/OpenTutorials_PyQt/1fff4b33fe286377f1263e265480dda9026fe65f/QtFramework/QtWidgets/ItemViews_model_based/shield.png -------------------------------------------------------------------------------- /QtFramework/QtWidgets/ItemViews_model_based/sword.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RavenKyu/OpenTutorials_PyQt/1fff4b33fe286377f1263e265480dda9026fe65f/QtFramework/QtWidgets/ItemViews_model_based/sword.png -------------------------------------------------------------------------------- /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/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_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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/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/QTabWidget/plus_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RavenKyu/OpenTutorials_PyQt/1fff4b33fe286377f1263e265480dda9026fe65f/QtFramework/QtWidgets/QTabWidget/plus_icon.png -------------------------------------------------------------------------------- /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/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/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/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/QToolBar/assets/icon_split_horizontal.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /QtFramework/QtWidgets/QToolBar/assets/icon_split_vertical.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /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/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/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/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/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 | -------------------------------------------------------------------------------- /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/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/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/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_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/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/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_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_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 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /QtFramework/QtWidgets/QWebEngineView/html/snow.swf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RavenKyu/OpenTutorials_PyQt/1fff4b33fe286377f1263e265480dda9026fe65f/QtFramework/QtWidgets/QWebEngineView/html/snow.swf -------------------------------------------------------------------------------- /QtFramework/QtWidgets/QWebEngineView/images/go-next.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RavenKyu/OpenTutorials_PyQt/1fff4b33fe286377f1263e265480dda9026fe65f/QtFramework/QtWidgets/QWebEngineView/images/go-next.png -------------------------------------------------------------------------------- /QtFramework/QtWidgets/QWebEngineView/images/go-previous.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RavenKyu/OpenTutorials_PyQt/1fff4b33fe286377f1263e265480dda9026fe65f/QtFramework/QtWidgets/QWebEngineView/images/go-previous.png -------------------------------------------------------------------------------- /QtFramework/QtWidgets/QWebEngineView/images/process-stop.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RavenKyu/OpenTutorials_PyQt/1fff4b33fe286377f1263e265480dda9026fe65f/QtFramework/QtWidgets/QWebEngineView/images/process-stop.png -------------------------------------------------------------------------------- /QtFramework/QtWidgets/QWebEngineView/images/view-dom_tree.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RavenKyu/OpenTutorials_PyQt/1fff4b33fe286377f1263e265480dda9026fe65f/QtFramework/QtWidgets/QWebEngineView/images/view-dom_tree.png -------------------------------------------------------------------------------- /QtFramework/QtWidgets/QWebEngineView/images/view-refresh.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RavenKyu/OpenTutorials_PyQt/1fff4b33fe286377f1263e265480dda9026fe65f/QtFramework/QtWidgets/QWebEngineView/images/view-refresh.png -------------------------------------------------------------------------------- /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/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/qwebchannel.qrc: -------------------------------------------------------------------------------- 1 | 
 2 | 
 3 | js/qwebchannel.js
 4 | 
 5 | -------------------------------------------------------------------------------- /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/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/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/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/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/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/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/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/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/QWidget/shield.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RavenKyu/OpenTutorials_PyQt/1fff4b33fe286377f1263e265480dda9026fe65f/QtFramework/QtWidgets/QWidget/shield.png -------------------------------------------------------------------------------- /QtFramework/QtWidgets/QWidget/sword.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RavenKyu/OpenTutorials_PyQt/1fff4b33fe286377f1263e265480dda9026fe65f/QtFramework/QtWidgets/QWidget/sword.png -------------------------------------------------------------------------------- /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/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/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/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_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/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/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/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/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/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/README.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/RavenKyu/OpenTutorials_PyQt/1fff4b33fe286377f1263e265480dda9026fe65f/QtFramework/README.md -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # OpenTutorials_PyQt 2 | 만들면서 배우는 PyQt 프로젝트 모음 3 | --------------------------------------------------------------------------------