CMFCPropertyGridCtrl에 대한 정리

이미지
저는 C++로 GUI를 구현할 때 MFC ( M icrosoft F oundation C lass)를 자주 사용합니다. MFC는 MS가 windows API 함수 들을 Wapper class형태로 구현해 놓은 것을 뜻합니다. 처음 프로그래밍을 배우던 시절 Visual Studio 6.0 을 사용하면서 습관화 되어 MFC가 익숙하지만 요즘은 Qt를 더 자주 사용하게 됩니다. 무료라는 점도 MFC를 더 자주 사용했던 이유중에 하나입니다. 입력값이 많은 프로그램 개발 시 문제 MFC를 사용하며 느끼는 불편함은 여러 가지지만, 특히 규모가 큰 프로젝트 진행 시 입,출력 값이 많다면 CEdit 컨트롤 을 너무 많이 생성해야 하는 불편함이 존재합니다. 대화상자 편집기에서 직접 컨트롤을 배치하든, 소스코드에서 동적 할당해 사용하든 상관없이 말이죠. [복잡한 입력값 처리 예시] 하나의 대화상자에 배치할 컨트롤이 너무 많아도 보기 싫고, 그렇다고 대화상자를 여러개 만들어도 사용하기가 불편합니다. 물론, DB or 파일에서 데이터를 읽어들여 사용하는 방법도 있겠으나, 가능하면 다양한 설정치를 소프트웨어에서 사용자가 쉽게 변경하고 변경치를 즉시 확인해가며 진행하는 방식 (예를 들면 시뮬레이션 분야 등) 에서는 답이 없습니다. 복잡한 UI 대안은? 이런 경우 MFC의 좋은 대안이 있습니다. Visual Studio 2008 부터 (Feature Pack 설치 시) 지원되는 (이후 버전부터 기본적으로 지원) CMFCPropertyGridCtrl 가 그 주인공입니다. 화면이 친숙한데, Visual Studio에 속성창으로 자주 사용되는 컨트롤 입니다.   [CMFCPropertyGridCtrl cl...

OpenCV기반의 얼굴, 눈 인식 앱 제작

이미지
대학교 졸업 후 DVR (Digital Video Recorder) 을 프로그래밍할 기회가 있었습니다. DVR은 쉽게 다수의 CCTV 카메라 영상을 녹화해 저장하는 장치입니다. 제가 만든 제품이 부산 사직야구장에 설치되었으며, 현재는 시간이 오래되어 아마 다른 제품이 설치되어 있을 것입니다. 당시, 녹화용량을 줄이기 위해 동영상의 정지 영상을 한 프레임씩 가져와 이전 프레임과 비교해 픽셀의 변화가 있는 경우 (움직임 감지) 저장하는 방식으로 구현했던 기억이 납니다. 요즘은 영상처리기술이 얼마나 진보했나 싶어 자료를 찾아보다 OpenCV 를 이용해 쉽게 얼굴, 눈, 전신, 상체, 하체 등을 인식하는 방법이 있어 소개합니다. 이 프로그램은 Python + OpenCV + PyQt5를 이용해 제작되었습니다. 프로그램 실행파일의 경로에 아래에 소개된 Haar Cascades.xml 파일이 같이 위치해야 합니다. Pyinstaller로 제작된 실행파일 링크 (PyQt5와 OpenCV 모듈에 필한 dll, lib 가 모두 single exe로 포함되어 용량(약 80MB)이 큽니다)  좋아하는 배우인 이선균씨 얼굴을 핸드폰에 띄우고 노트북 웹캠으로 얼굴, 눈을 인식해 봤습니다. [실행 화면] OpenCV 를 이용해 만들었으므로, 컴퓨터 비전에 대한 지식이 없어도 무방합니다. 아래 동영상은 포토샵의 '레나' 이미지를 인식시켜 본 결과입니다.   OpenCV 란? 실시간 컴퓨터 비전을 목적으로 인텔에서 C++로 만든 크로스 플랫폼 라이브러리 파이썬에서도 python -m pip install opencv-python 으로 설치 후 사용 가능 ...

효율적으로 약수를 구하는 방법

이미지
파이썬으로 약수(divisor) 를 구하는 방법을 살펴보겠습니다. 만들다 보니 여러수를 입력해 공약수 와 최대 공약수 까지 구하도록 확장시켜 보았습니다. 예를 들면 12의 약수는 12를 1(n)부터 12(n)까지 나누기 한 후 나머지가 0이면 n은 약수 12 / 1 = 나머지 0 이므로 1은 약수 12 / 2 = 나머지 0 이므로 2도 약수...(반복)  따라서 12를 나누어 떨어지는 수는 1, 2, 3, 4, 6, 12 입니다. 만약 12와 16의 공약수를 구한다면 12의 약수 : 1, 2, 3, 4 , 6, 12 16의 약수 : 1, 2, 4 , 8, 16 12와 16의 공약수 : 1, 2, 4 따라서, 최대공약수는 4 [여러수의 약수, 공약수, 최대공약수 구하기] 조건  위 방식을 이용해 아래 미션을 수행해 보았습니다. 100,000,000의 약수를 구하라. (일억) 방법 1 : 단순하게 1부터 약수를 구하고자 하는 수까지 반복 import time cnt = int(input('약수를 구할 횟수 입력:')) divs = [] for i in range(cnt): n = int(input('숫자 입력:')) d = [] s = time.time() for i in range(1, n+1): if n%i == 0: d.append(i) divs.append(set(d)) print(n,'의 약수 : ', *d, '소요시간 : ', time.time()-s,'(sec)') print() if cnt>1: comdiv = set.inter...

RTTI에 대한 이해

이미지
이번에는 C++의 RTTI ( R un t ime T ype I ndentification) 에 대해 소개하고자 합니다. 다형성(Polymorphism) 을 갖는 C++ class 들(하나 이상의 가상함수를 포함)에 대해 적용 가능합니다. 클래스 다형성은 가상함수에 의해 구현되므로, RTTI는 가상함수를 갖는 클래스의 상속관계에서만 사용가능 합니다. 아마도 이 주제를 찾아 보는 사용자라면 알고 있겠지만, C++ 포인터와 클래스 상속에 대한 이해가 요구됩니다. RTTI 런타임에 상속 관계를 갖는 클래스들의 객체 타입을 체크 하는 메커니즘. dynamic_cast or typeid 연산자로 구성. 가상함수(Virtual Fucntion)를 가지는 클래스들만 사용 가능.  왜 RTTI 가 필요한지 코드를 통해 살펴보겠습니다. 안전하지 않은 타입 캐스팅 #include <iostream> using namespace std; class CWnd { virtual void draw() { cout << "CWnd" << endl; } }; class CView:public CWnd { public: int m_view; void draw() { cout << "View" << endl; } }; class CTreeView :public CView { public: int m_treeview; void draw() { cout << "Tree View" << endl; } }; int main() { // 부모클래스 포인터는 자식 클래스 객체를 가르킬 수 있다. CWnd *pw = new CWnd; CWnd *pv = new CView; CWnd *pt = new CTreeView; ...

PyQt와 피타고라스정리를 이용한 양궁 게임

이미지
개요 이번에 만든 파이썬 예제는 양궁게임(Archery Game) 입니다. 마우스를 클릭하면 움직이는 QProgressBar (수평, 수직) 를 이용해 x, y  좌표를 설정하고 과녁에 맞춘 위치 표시합니다. 심화반 초등학생이 C++, MFC로 만든 양궁게임에서 영감을 얻어 Python과 PyQt5를 이용해 만들해 보았습니다. [양궁게임 실행화면] 설계 과정 1. 윈도우 창의 하단, 우측에 수평, 수직 QProgressBar를 배치 (X, Y 좌표 얻기 용도) 2. QFrame을 이용해 양궁 과녁판 제작 (정사각형) [과녁판] 3. 양궁 과녁 점수판 사각형 영역 얻기 (과녁 사각형을 줄여가며) [과녁 점수판 영역 설정] 4. 사각형에 내접하는 원으로 그리기 [과녁 점수판 원으로 표현] 5. 과녁 색상 입히기 [과녁 완성 모습] 6. 피타고라스의 정리를 이용해 점수 구하기 [화살 좌표로 점수 구하기] 좀 더 세부적인 내용은 소스코드를 보며 알아보겠습니다. 소스코드 2개의 파이썬 파일로 구성 (main.py, archery.py) main.py import sys fro...

PyQt로 구현한 아날로그 시계 2편

이미지
NTP에 대해 설명한 아날로그 시계 1편 에 이어, 실제 Analog Clock을 그리는 2편입니다. Python에서 NTP(Network Time Protocol)을 이용한 시간 얻기 는 1편을 참조하기 바랍니다. 2편에서는 얻어진 시간정보로 아날로그 시계를 그리는 방법 에 대해 살펴보겠습니다. 완성된 모습은 아래와 같습니다. pyinstaller 실행파일 링크 : Analog Clock.exe [Python Analog Clock] 자세한 개요는 1편에 있으므로, 바로 소스코드를 분석해 보겠습니다. 소스 코드 분석 전체 코드는 2개의 파이썬 파일로 구성되어 있으며(main.py, NTP.py), 이번 시간에는 시계를 그려내는 main.py 파일을 살펴보겠습니다. 프로그램을 실행하기 위해서는 1편의 NTP.py 파일과 2편의 main.py 파일 2개가 필요합니다. NTP.py ( 1편 참조 ) main.py 윈도우 창을 구성하고, 시계외형 원, 시간표시, 시, 분, 초침, 날짜 등을 그리는 역할입니다. 세부내용은 아래 main.py 전체 코드 를 살펴보고 설명하겠습니다. import sys import math from PyQt5.QtCore import * from PyQt5.QtGui import * from PyQt5.QtWidgets import * from NTP import NTP from threading import Thread import time QApplication.setAttribute(Qt.AA_EnableHighDpiScaling, True) class CWidget(QWidget): displayUpdate = pyqtSignal() def __init__(self): super().__init__() ...

이 블로그의 인기 게시물

Qt Designer 설치하기

PyQt5 기반 동영상 플레이어앱 만들기