반응형

파이썬 GUI PyQt5(2) - QtDesigner Push button 이벤트 signal/slot 연동

 

1. QtDesigner로 창 띄우는 방법

https://zidarn87.tistory.com/256?category=415247 

 

파이썬 GUI PyQt5(1) - QtDesigner를 이용한 간단한 창 띄워보기

파이썬 GUI PyQt5(1) - QtDesigner를 이용한 창 띄우기 1. PyQt5를 사용하기 위한 준비하기 - Python 개발 IDE인 PyCharm 설치하기 (다운로드 PyCharm: JetBrains가 만든 전문 개발자용 Python IDE) - Qt Designer..

zidarn87.tistory.com

 

2. QtDeigner에서 ui 버튼 생성 및 signal / slot 연동

왼쪽 위젯박스에서 Push Button과 Label 컴포넌트를 왼쪽의 My First Application 창에 드래그해서 생성합니다.

Label과 Push button 속성 중 Object 이름과 text를 지정해봅니다. 

Object 이름은 파이썬 코드에서 해당 컴포넌트를 참조하여, 설정 및 동작을 하기 위해 사용됩니다. 

start 버튼을 눌렀을 때, Label의 text를 start로 변경하고, stop 버튼을 눌렀을 때에는 Label의 text를 stop으로 변경해 보도록 하겠습니다.

이제는 signal/slot를 지정해 봅니다. 

Edit siglal/slot 모드로 변경합니다. 

그리고 start 이름을 가진 push button을 클릭하고 아래로 드래그 하여, Confiture Connection 창의 띄웁니다.

Edit 버튼을 눌러 Slot을 만들어 줍니다.

이제 signal과 slot을 연결해줍니다. 

왼쪽은 이벤트가 발생할 때의 signal로 보시면 되고, 오른쪽은 slot입니다. 

버튼을 클릭했을 때의 동작되도록 하기 위해, clicked() 시그널과 start() 슬롯을 연결해줍니다. 

이제 파이썬 코드에서 start() slot에 대한 함수를 만들어, 어떠한 동작을 실행시킬지를 정의해주면 됩니다. 

start 버튼과 stop 버튼의 이벤트에 대한 slot을 연결하였습니다. 

이제 파일을 저장하고, 파이썬 코드를 작성하겠습니다.

s

3. 파이썬 코드로 slot에 대한 함수 생성 및 정의

위에서 만든 ui 파일을 로그하고, Qt Designer에서 만든 slot을 정의하지 않고 파이썬 코드를 실행하면 아래와 같은 에러가 발생합니다. 

하여, start slot 함수와 stop slot 함수를 생성해보도록 하겠습니다. 

아래 코드에서 uic.loadUi("./file/myapp.ui") 코드를 uic.loadUi("./file/myapp.ui", self) 로 변경해주어야 slot 함수를 제대로 인식하여 에러가 발생되지 않습니다. 

slot 함수를 생성하고, 정의하였습니다. 

 start 버튼을 누르면 start() 함수가 호출되고, stop 버튼을 누르면 stop() 함수가 호출됩니다. 

호출 되었을 때, label_status를 참조하여, Label 컴포넌트의 text를 변경하도록 하였습니다. 

    def start(self):
        self.ui.label_status.setText("start")
    def stop(self):
        self.ui.label_status.setText("stop")

실행해보면 아래와 같이 출력됩니다. 

4. 전체 코드

import sys
from PyQt5 import QtWidgets
from PyQt5 import uic

class MyApp(QtWidgets.QDialog):
    def __init__(self, parent = None):
        super().__init__(parent)
        self.ui = uic.loadUi("./file/myapp.ui", self) # 두번째 전달인자에 self를 넣어주어야 합니다.
        self.ui.show()
    def start(self):
        self.ui.label_status.setText("start")
    def stop(self):
        self.ui.label_status.setText("stop")

app = QtWidgets.QApplication(sys.argv)
me = MyApp()
sys.exit(app.exec())

 

반응형
반응형

파이썬 GUI tkinter / dataframe의 내용을 Listbox, Label로 표시

 

 

1) numpy 배열로 data frame 생성

Listbox에 넣을 이름과 Label에 정보를 표시할 성별과 태어난 해 정보를 가지고 배열을 만듭니다. 

배열을 DataFrame으로 생성합니다. 

# numpy 배열로 data frame 생성
my_darray = np.array([
    ["Bob", "M", 1991],
    ["Kate", "W", 1992],
    ["Kevin", "M", 1993],
    ["Scott","M",1994],
    ["Jackson", "M", 1995],
    ["Liam", "M", 1996],
    ["Noah", "M", 1997],
    ["Aiden", "M", 1998],
    ["Lucas", "M", 1999],
    ["Mason", "M", 2000]])
student_pd = pd.DataFrame(my_darray)
print(student_pd)
print(student_pd.shape)
print(len(student_pd))

 

 

2) Tkinter로 window 생성 및 ListBox 생성

간단하게 Tk() 생성자로 window를 생성하였고, 크기를 지정하였습니다. 

또한 Listbox 를 생성하였고, Listbox 안의 column이 선택되었을 때, CurSelect(임의 생성 함수)가 호출되도록 하였습니다.

 

그리고 리스트에는 dataframe의 이름을 삽입하도록 하였고, 리스트의 맨뒤쪽(END)에 삽입이되도록 하였습니다. 

window = Tk()
window.geometry("300x200")

lb = Listbox(window, height=5, selectmode=SINGLE)
lb.bind('<<ListboxSelect>>',CurSelect)
lb.pack()

for i in student_pd.index:
    val = student_pd.loc[i, 0]
    lb.insert(END, val)

 

3) Label 생성

고정으로 표시할 Label과 이름, 성별, 태어난 해에 대한 정보를 동적으로 가져와 표시할 라벨을 생성하였습니다.

Name_l = Label(window, text="Name : ")
Name_l.pack()
Name_w = Label(window, text="")
Name_w.pack()

Sex_l = Label(window, text="Sex : ")
Sex_l.pack()
Sex_w = Label(window, text="")
Sex_w.pack()

Birth_l = Label(window, text="Birth : ")
Birth_l.pack()
Birth_w = Label(window, text="")
Birth_w.pack()

 

4) Listbox에 아이템이 선택되었을 때의 호출되는 함수 정의

lb.curselection() 함수를 이용해 현재 선택된 아이템의 정보를 가져오고, 출력해보게 하였습니다. 

그리고 Label에 현재 선택된 아이템의 이름, 성별, 태어난 해를 표시하도록 하였습니다.  

def CurSelect(evt):
    value = str((lb.get(lb.curselection())))
    index = str((lb.index(lb.curselection())))
    print(value)
    print(index)

    Name_w["text"]  = student_pd.loc[lb.index(lb.curselection()), 0]
    Sex_w["text"]   = student_pd.loc[lb.index(lb.curselection()), 1]
    Birth_w["text"] = student_pd.loc[lb.index(lb.curselection()), 2]

 

 

전체 코드

import numpy as np
import pandas as pd
from tkinter import *

# numpy 배열로 data frame 생성
my_darray = np.array([
    ["Bob", "M", 1991],
    ["Kate", "W", 1992],
    ["Kevin", "M", 1993],
    ["Scott","M",1994],
    ["Jackson", "M", 1995],
    ["Liam", "M", 1996],
    ["Noah", "M", 1997],
    ["Aiden", "M", 1998],
    ["Lucas", "M", 1999],
    ["Mason", "M", 2000]])
student_pd = pd.DataFrame(my_darray)
print(student_pd)
print(student_pd.shape)
print(len(student_pd))

def CurSelect(evt):
    value = str((lb.get(lb.curselection())))
    index = str((lb.index(lb.curselection())))
    print(value)
    print(index)

    Name_w["text"]  = student_pd.loc[lb.index(lb.curselection()), 0]
    Sex_w["text"]   = student_pd.loc[lb.index(lb.curselection()), 1]
    Birth_w["text"] = student_pd.loc[lb.index(lb.curselection()), 2]

window = Tk()
window.geometry("300x200")

lb = Listbox(window, height=5, selectmode=SINGLE)
lb.bind('<<ListboxSelect>>',CurSelect)
lb.pack()

for i in student_pd.index:
    val = student_pd.loc[i, 0]
    lb.insert(END, val)

Name_l = Label(window, text="Name : ")
Name_l.pack()
Name_w = Label(window, text="")
Name_w.pack()

Sex_l = Label(window, text="Sex : ")
Sex_l.pack()
Sex_w = Label(window, text="")
Sex_w.pack()

Birth_l = Label(window, text="Birth : ")
Birth_l.pack()
Birth_w = Label(window, text="")
Birth_w.pack()

window.mainloop()
반응형
반응형

QT qml의 TextField, Button을 이용한 문구 출력

 

QML을 이용해 GUI 프로그램을 만들기 위해 프로젝트 생성은 아래 링크를 참고하시면 됩니다.

https://zidarn87.tistory.com/9?category=415008 

 

QT - Widget, Console, Quick 프로젝트 생성하여 Hello world 출력하기

QT - Widget, Console, Quick 프로젝트 생성하여 Hello world 출력하기 1. Qt Widgets Application으로 Hello world 출력하기 Qt Widgets Application을 만들고 계속 Next를 누른다. 프로젝트를 생성하면 아래와..

zidarn87.tistory.com

 

Button을 눌렀을 때 TextField에 입력된 text를 label에 업데이트하는 것을 구현해 봅니다.

Qt의 Cpp 쪽으로 데이터를 보내지 않고, qml에 내에서만 코드를 작성해 볼게요.

 

 

"Name : " 문구를 표시한 Label과 TextField로부터 받아온 문구를 표시할 Label을 생성하였습니다. 

displayname Label의 위치는 namelabel의 아래 쪽에 위치하도록 하였습니다.  

 

    Label{
        id : namelabel
        x: parent.x
        font.pointSize: 20
        text : "Name : "
    }

    Label{
        id : displayname
        y: namelabel.height + 30
        font.pointSize: 20
        text : "No input"
    }

 

text를 입력받을 TextField를 생성하였습니다. 

위치는 namelabel의 오른쪽에 위치하도록 하였습니다. 

    TextField {
        id:textfield
        x:namelabel.width
        width: 200
        placeholderText: qsTr("Enter name")
        font.pointSize: 20
    }

 

Buttom 컴포넌트를 생성하였습니다. 

위치는 textfield의 오른쪽에 위치하도록 하였고, button을 클릭하였을 때, displayname Label의 문구를 업데이트 하도록 구현하였습니다. 

    Button{
        x: textfield.x + textfield.width + 10
        text: "Button"
        onClicked: buttonClickProcess()

        function buttonClickProcess(){
            displayname.text = "my name is " + textfield.text
        }
    }

 

전체 qml의 코드는 아래와 같습니다. 

 

import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.Controls 2.12

Window {
    visible: true
    width: 640
    height: 480
    title: qsTr("First Program")

    Label{
        id : namelabel
        x: parent.x
        font.pointSize: 20
        text : "Name : "
    }

    Label{
        id : displayname
        y: namelabel.height + 30
        font.pointSize: 20
        text : "No input"
    }

    TextField {
        id:textfield
        x:namelabel.width
        width: 200
        placeholderText: qsTr("Enter name")
        font.pointSize: 20
    }

    Button{
        x: textfield.x + textfield.width + 10
        text: "Button"
        onClicked: buttonClickProcess()

        function buttonClickProcess(){
            displayname.text = "my name is " + textfield.text
        }
    }
}
반응형

+ Recent posts