기록으로 남기기 위해서.

int value = 300;

int usedStorage = 9267822;//단위 MB

int totalStorage = 29284517;//단위 MB

MVS2015 / QT5에서 하기 수식을 수행하면,

int result = ceil(value * usedStorage / totalStorage);// ERROR : -51

원하는 result를 얻으려면,

각각을 일정 값 이하로 줄인 다음에 비율을 구한다.

int temp_value = usedStorage / 1024;

int temp_storage = totalStorage / 1024;

result = ceil(value * temp_value / temp_storage);//8 !!!!!

by 무위자연 2019.07.04 14:22

다음 데이터를 조건에 의해서 기대 결과로 나오게 하는 쿼리

데이터 : 1, 2, 2, 3, 3, 4, 5, 5, 5

기대 결과 : 5, 1,2, 2, 3, 3, 4

#1 union all을 쓰는 방법

select * from tableA where itemid = 3605255 and name like '%.exe' group by type

UNION ALL

select * from tableA where itemid = 3605255 and isHidden != 1 and name not like '%.exe';

UNION ALL 관련 페이지 : http://intomysql.blogspot.com/2011/01/union-union-all.html

 

UNION과 UNION ALL 의 차이 및 주의 사항

ANSI SQL에서 제안하는 집합 연산 "UNION", "INTERSECT", "MINUS" 중에서 MySQL에서는 UNION 집합 연산만 제공 하고 있다. (하지만 MySQL에서 INTERSECT나 MINUS를 다른 형태의 쿼리로 풀어서 사용할 수 ...

intomysql.blogspot.com

19.5.14 추가사항

#1-1union 이 포함된 쿼리문에 정렬을 넣으려고 할 때

a. union 각 쿼리에 정렬을 한 다음에 합치는 방법

Select * from ( %1) UNION ALL Select * from ( %2 )

%1, %2가 각 정렬이 적용된 쿼리를 넣어서 사용한다.

b. union으로 합친 결과 물에 정렬을 적용하는 방법

Select * from (%1 UNION ALL %2 ) %3

%3에 "order by ..."을 적용한다.

 

 

#2 sqlite의 rowid를 사용하는 방법

select * from ( SELECT name, CASE when name like '%.exe' THEN 0 ELSE ROWID END id FROM tableA where itemid = 3605255 )x group by x.id order by x.id ASC;

오라클은 가상의 sequencial한 id가 존재하고 이것으로 정렬 등에 사용한다.

sqlite도 유사하게 rowid란 가상의 sequencail한 id가 있어서 사용할 수 있다.

rowid 개념 관련 글 : https://ohgyun.com/698 

 

sqlite: limit (오라클의 rownum 기능)

발생일: 2015.12.29 키워드: sqlite3, limit, oracle rownum 문제: sqllite 에서 오라클에서 제공하는 rownum 기능은 뭘까? 해결책: SQLite는 limit라는 기능을 제공한다. SELECT COL1, COL2 FROM TAB01 ORDER BY..

ohgyun.com

 

by 무위자연 2019.05.09 14:18

김제동

19.4.17~5.2

상식적인 사회

그래서 우리가 행복지는 것에 대해서 이야기하자는 거다

헌법이 누구나 이야기할 수 있었으면 좋겠다

누가 누구를 비난하고 공격하고자하는 이야기가 아니다

국민이라면 누구나 당연히 받아야하는 권리를 보호하기 위한 것이다.

안 지켜지는 것도 있지만 최소한 방향 제시는 하고 있다

아는 만큼 더 보이지만 따뜻한 이야기다.

특정인에 대한 추모도 있고 어떤 단체나 사람에겐 비난 보단 가벼운 비판도 있다

 

http://www.yes24.com/Product/Goods/63691247?scode=032&OzSrank=1

by 무위자연 2019.05.03 08:16
더스틴 보즈웰, 트레비 파우커 지음 / 한빛미디어

18.12.21-19.3.13

PART FOUR 선택된 주제들
[15]'분/시간 카운터'를 설계하고 구현하기

[14] 테스트와 가독성
테스트를 위한 코드는 쉽고 간결하게 써져야 하고 변경도 쉬워야 한다.

테스트시에 나오는 메시지도 신경 써서 만들어야 한다. 읽기 편하게. 그리고 원인을 쉽게 알 수 있게

테스트의 범위가 명확해야 한다.

하지만 테스트를 위해서 원래 코드가 나빠지면 곤란하다.

PART THREE 코드 재작성하기
[13]코드 분량 줄이기
가장 읽기 쉬운 코드는 아무 것도 없는 코드다
개발자가 짜고 싶은 코드나 기능? 하지마.
코드 베이스는 작게작게 - 기능을 줄이던, 라이브러리를 쓰던,
결국 다 테스트해야 한다

사용하지 않는 코드를 제거해라.

사용하는 라이브러리에 친숙해져라.
이거 관련된 뭔가가 있었는데 정도면 충분하다.


[12] 생각을 코드로 만들기
1 코드가 할 일을 옆의 동료에세 말하듯이 평범한 영어로 묘사해라
2 이 설명에 들어가는 핵심적인 단어와 문구를 포착하라
3 설명과 부합하는 코드를 작성하라

[11] 한번에 하나씩
한 번에 여러 가지 일을 수행하는 코드는 이해하기 어렵다.

*한번에 하나의 작업만 수행하게 코드를 구성해야 한다.
함수형 프로그래밍의 기본이기도 하다.


[10] 상관 없는 하위 문제 추출하기
1 주어진 함수나 코드 블록을 보고 스스로 질문하라 "상위 수준에서 본 이 코드의 목적은 무엇인가?"
2 코드의 모든 줄에 질문을 던져라 '이 코드는 직접적으로 목적을 위해서 존재하는가? 혹은 목적을 위해서 필요하긴 하지만 목적 자체와 직접적으로 상관 없는 하위 문제를 해결하는가?"
3 만약 상당히 원래의 목적과 직접적으로 관련되지 않은 하위 문제를 해결하는 코드 분량이 많으면, 이를 추출해서 별도의 함수로 만든다.

해당 함수, 클래스는 본인의 목적에 충실해야 한다. 하위 문제를 해결하는 코드가 많으면 추출해라.
너무 작은 단위로 추출하면 그게 또 나쁘다.

PART2 
루프와 논리를 단순화하기

[9] 변수와 가독성
변수를 엉터리로 사용하면 다음과 같은 문제가 발생한다
1 변수의 수가 많을 수록 기억하고 다루기 더 어려워진다
2 변수의 범위가 넓어질수록 기억하고 다루는 시간이 더 길어진다
3 변수값이 자주 바뀔수록 현재값을 기억하고 다루기가 더 어려워진다.

*변수 제거하기
불필요한 임시변수 제거하기
중간 값을 저장하는 변수 제거하기
흐름제어 변수 제거하기

*변수의 범위를 좁혀라
"전역 변수를 피하라"
범위가 넓으면 수정 및 사용영역을 가늠하기 힘들다.
- 변수가 적용되는 범위를 최대한 좁게 만들어라

- 많은 메소드를 정적 static으로 만들어서 클래스 멤버 접근을 제한하라 > 가급적 정적 메소드는 사람들에게 저 변수들로부터 독립적이라는 메시지를 줘야 한다 >>> 이것이 fn?
- 커다란 클래스를 여러 작은 클래스로 나누는 것도 방법이다.
변수 선언은 미리 앞단에 선언하는 것이 아니라
 그 때 그때 쓸 때 선언하는 것이 생각의 흐름에 적합한 편이다.

*값을 한번만 할당하는 변수를 선호하라
최대한 적게 변하는게 좋고 변하지 않아야 하는건 const 같은 키워드를 활용한다.



[8]거대한 표현을 잘게 쪼개기
*거대란 표현을 더 소화하기 쉬운 여러 조각으로 나눈다.

*거대한 구문 나누기

*표현을 단순화 하는 다른 창의적인 방법들
표현이 명확하고 버그를 만들 가능성이 적으면 매크로를 써서 가독성을 높인다.
하지만 이 말이 매크로를 권장한다는 것은 아니다.

-설명변수
if line.split(':').[0].strip() == "roor": 보다는

username = line.split(':').[0].strip()
if username == "root" 가 낫다.

-요약변수

and or 조건을 1줄에 축약하는 것보다 의미가 명확해진다면
2줄도 좋다는 생각을 가지자.

'영리하게' 작성된 코드에 유의하라, 나중에 다른 사람이 읽으면 그런 코드가 종종 혼란을 초래한다.

-복잡한 논리와 씨름하기
복잡한 논리가 중첩 되면 버그가 양산되니.
반대로 생각하는 것이 더 쉬울수 있다!


[7] 읽기 쉽게 흐름제어 만들기
*흐름을 제어하는 조건과 루프 그리고 여타 요소를 최대한 '자연스럽게 만들려고 노력해라
코드를 읽다가 다시 되돌아 가서 코드를 읽지 않아도 되게끔 만들어야 한다.

*if/else 블록의 순서
1-부정이 아닌 긍정 조건을 먼저
예. if(!debug) 보다 if(debug)
2-간단한 것을 먼저 처리하고
3-흥미롭고 확실한 것을 먼저
난 2번 보다 3번을 주로 선택해서 continue/ return이 늦게 나왓던 듯...팀장/소장에 비해서

3항 연산자는 가독성을 보고 가독성이 높아지는 조건에서만 쓰면 되겠다.
A ? B : C 인 경우
조건이 복잡하면 가독성이 떨어지나 조건이 간단하면 3항 연산자가 더 좋다.

*do/while loop를 피하라
조건이 뒤에 있고 한번을 실행해야 하고 continue를 쓰면 혼란스러우니 피하자
while을 쓰자

*함수 중간에서 반환하기
한 함수의 반환이 중간에 여러 번 있어도 전혀 문제가 없으니까 막 반환하자.

대신 클린업 보드를 위한 관용적인 구조를 이용한다
C++ : 소멸자
자바,파이썬 : try finally
파이썬 : with
c# : using

*악명 높은 goto
c를 제외하고 안 써야 한다
c도 줄여야 한다. 피할 수 있을 때까지 피해야 한다.

*중첩을 최소화하기
if / else 조건은 간단해야 좋고
조건의 중첩을 줄여야 한다.
담당 개발자에게 각 step 별로 중첩이 당연해보여도
그런 중첩이 일어난 상태에서 그 코드를 처음 보는 사람은 당황스럽다.
수정해야 하는 상황이라면 여러분의 코드를 새로운 관점에서 바라보라

함수 중간에서 반환하여 중첩을 줄여라.

루프내에 있는 중첩을 제거하기
<기존>
for(
   if(condition) {
      if() //
          if() //
   }//이게 내가 하덧 짓
<제안>

for(
 if(!condition)
    continue
    if()
       continue
         if()

*실행 흐름을 따라올 수 있는가?
쓰레딩 / 시그널,인터럽트 구조 / 예외 / 함수포인터&익명 함수 / 가상 메소드는
코드를 이해하기 어렵기 때문에 핵심 코드에서 지양하고 최소화한다

PART1 표면적인 수준에서의 개선

[6] 명확하고 간결한 주석 달기
*주석을 간결하게 하라
*모호한 대명사는 피해라
*

[5] 주석에 담아야 하는 대상
* 주석의 목적은 코드를 읽는 사람이 코드를 작성한 사람만큼 코드를 잘 이해하는데 돕는데 있다.

*설명하지 말아야 하는 것

코드에서 유추할 수 있는 것은 넣지 마라
예. //클래스 A를 위한 정의 //생성자 //이 값을 bool으로 반환 

나쁜 이름에 주석을 달지 말아라. 대신 이름을 고쳐라
좋은 이름의 함수가 좋은 주석보다 낫다

* 코딩을 수행하면서 머릿속에 있는 정보 기록하기

director's cut 같은 내용을 적어놔라

//이 주먹구구식 논리는 몇가지 단어를 생략할수 있다. 100% 해결은 어렵다
//이 클래스는 점점 엉망이 되고 있다. 어쩌면 하위 클래스를 만들어야 할지도 모름

그래야 최소 이 클래스의 상태를 보고 헛짓을 안 할 수 있다!

코드에 있는 결함을 설명하라
//todo : 더 빠른 알고리즘 필요
//todo(더스틴) : JPG말고 다른 포맷도 처리할 수 있어야 한다.
개선이 필요한 부분을 언급하는 것을 부끄러워 하지 마라 코드는 계속 진화해야 하니까.
흔히 쓰는 주석 키워드
todo : 할 것
fixme : 오작동이 알려진 코드
hack : 아름답지 않은 해결책
xxx: 위험해 여기

상수에 대한 설명은 가급적 하는 편이 낫다

* 코드를 읽는 사람의 입장에서 필요한 정보가 무엇인지 유추하기
나올 것 같은 질문에 대해선 주석 달기
코드를 작성할 때 "내가 작성한 이 코드를 다른 사람이 읽으면 깜짝 놀랄만한 부분이 있나?"를 생각해보자

큰 그림에 대한 주석~

복잡한 기능에 대한 요약 주석도 중요하다
라인별 함수별 주석이 있어도 무엇을 하는지에 대한 주석이 있어야 한다.

다음 단계로 주석을 단다
1 마음에 떠오르는 생각을 무조건 적어본다
2 주석을 읽고 무엇이 개선되어야 하는지 확인한다
3 개선한다.


[4] 미학
*일관성 있는 스타일은 '올바른'스타일이 더 중요하다.

*선언을 블록으로 나눠서 구분 짓게 하라

*의미 있는 순서를 선택하고 일관성 있게 사용하라
환자로 예로 들면
이름/성별/나이/주소 순으로 늘 비슷하게

*중복된 코드는 함수로 만들어 간결하게 만들어본다

*일관성과 간결성을 위해서 줄 바꿈을 재정렬하기
적절한 줄 바꿈과 들여쓰기는 가독성을 높인다.
일정한 글자수가 아니라.




좋은 소스는 '눈을 편하게'해야 한다.
- 코드를 읽은 사람이 이미 친숙한, 일관성 있는 레이아웃을 사용해라
- 비슷한 코드는 서로 비슷해보이게 하라
- 서로 연관된 코드는 하나의 블록으로 묶어라

요약
언제나 의미가 오해 되지 않는 이름이 최선의 이름이다.
의미에 대한 영어 단어의 한계가 있으니 max_, min_ 같은 접두어를 사용한다.

*이름을 짓기 위해서 복수의 후보를 평가한다.

* 사용자의 기대에 부응하기
getMean, list:size 등 반환이 바로 될거 같은 이름이지만,
아닌 경우도 있으므로 잘 파악해야 한다.
size란 이름은 O(1) 경우에만 붙여야 한다. 

* boolean 변수 이름 붙이기

예.bool read_password = true
의미가 모호하다.
우리는 패스워드를 읽을 필요가 있다 / 패스워드가 이미 읽혔다...
read같이 모호한 단어보다는
need_password | user_is_authenticated 같이 명시적인 단어를 사용하고

is, has, can, should 등의 단어를 이용한다.

부정적인 단어는 피한다.
bool disable_ssl = false;보단
bool use_ssl = true 가 더 읽기 좋다.


* 경계를 포함하는 범위에는 first / last를 써라.
시작은 포함하고 배열의 범위 밖까지 진행하는 것은 begin/end를 써라...이건 좀...지엽적인 듯한데.

* 경계를 포함하는 간게값을 다룰 때는 min / max를 이용해라.
한계를 설정하는 이름을 가장 명확하게 만드는 방법은 이름 앞에 max_, min_을 붙이는 것.
이상/초과, 이하/미만이 헷갈린다.
if shopping_cart.item_count > CART_TOO_BIG_LIMIT 보다는
if shopping_cart.item_count > MAX_ITEMS_IN_CART가 낫다~

[3] 오해할수 없는 이름들
본인이 지은 이름을 '다른 사람들이 다른 의미로 해석할수 있지 않을까? 라는 질문을 던져~

예. Filter
results = Database.all_objects.filter("year <= 2011")

문제점
대상을 고른다는 건지, 대상을 뺀다는 건지 알수가 없다
고른다면 select
빼는거라면 exclude가 더 낫다

예 Clip(text, length)
문장 끝에서 길이만큼 잘라낸다는 건지
문장을 처음부터 길이만큼 잘라내서 가진다는 건지 모호함

[2] 이름에 정보 담기

- 이름의 길이는?
좁은 범위에서는 짧은 이름이 괜찮다~
긴게 문제가 아니라 기억하기 어려운게 문제

흔한 약어는 괜찮다
evaluation > eval
document > doc
string > str

불필요한 단어는 제거하기

대문자/밑줄 등을 사용해라


-추상적인 이름보다 구체적인 이름을 선호하라.
변수명에 단위를 포함시키면 좋다.
밀리세컨드라면 _ms
초단위는 _secs
메가 바이트면 size_mb
다운로드 속도 단위는 max_kbps 등으로

-특정한 단어 오르기
size, get 으로 의미를 다 담기 어렵다
유의어 찾기, 동료에게 물어보기를 두려워하지 말라
- 재치 있는 이름보다 명확하고 간결한 이름이 더 좋다

tmp 같은 변수명은 전형적인 알고리즘 구현 내에서는 아주 좋지만
일반적인 기능에선 내용을 설명하지 못하니 안 좋다.
상황을 봐라

루프 반복자는 i,j, iter,it 보다 좋은 것을이 많다.
if(club[i].members[k] == users[j]) 보단
if(club[ci].members[mi] == user[ui]
ci 혹은 club_i, mi 혹은 members_i 같은 식이 버그 잡기 좋다
if(club[ci].members[ui] == user[mi] //index가 잘못된 상황임을 쉽게 알 수 있다.


1장 코드는 이해하기 쉬워야 한다.
코드는 이해하기 쉬워야 한다.
코드는 다른 사람이 그것을 이해햐는데 들이는 시간을 최소화하는 방식으로 작성되어야 한다.

내가 만든 코드도 6개월 지나면 어려워진다.
그러니 객관적으로 코드를 만들어야 한다.


by 무위자연 2019.03.13 16:55

QTableView의 ItemDelegate에서 해당 Row가 mouse hover 상태인지 직접 알수가 없다.


그래서 다음의 단계가 필요하다.


1. QTableView를 상속 받은 클래스를 만들고 해당 클래스는 다음과 같이 mousemove, mouse leaver에 대한 event를 처리하게 한다.

CustomTableView::CustomTableView(QWidget *parent) : QTableView(parent)

{

setMouseTracking(true);

}

void CustomTableView::mouseMoveEvent(QMouseEvent *event)

{

QModelIndex index = indexAt(event->pos());

emit hoverIndexChanged(index);

}

void CustomTableView::leaveEvent(QEvent *event)

{

emit leaveTableEvent();

viewport()->update();

}


2. 이 때 발생한 signal을 처리할 수 있도록 이 CustomTableView를 사용하는 곳에서 signal / slot을 설정한다.

connect(customTable_,

&ui::CustomTableView::hoverIndexChanged,

itemDelegate,

&ui::LoginInfoTableDelegate::slotHoverIndexChanged);

connect(loginInfoTable_,

&ui::CustomTableView::leaveTableEvent,

itemDelegate,

&ui::LoginInfoTableDelegate::slotLeaveTableEvent);


3. 사용할 ItemDelegate에서 다음과 같이 처리한다.

void CustomTableDelegate::slotHoverIndexChanged(const QModelIndex& item)

{

hoverRow_ = item.row();

}


void CustomTableDelegate::slotLeaveTableEvent()

{

hoverRow_ = -1;

}


4. 3번 slot으로 인해서 ItemDelegate의 Paint에서는 hoverRow_를 알 수 있게 된다.

void CustomTableDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const

{

int column = index.column();

QStyleOptionViewItem itemOption(option);

bool isHovered = false;

if (index.row() == hoverRow_)

{

itemOption.state = itemOption.state | QStyle::State_MouseOver;

isHovered = true;

}

else

{

itemOption.state = itemOption.state &  (~QStyle::State_MouseOver);

}


이제 마음껏 hover 되었을 때의 효과를 반영하면 된다~



by 무위자연 2019.03.13 13:48


참고 페이지 : https://doc.qt.io/Qt-5/qtprintsupport-index.html / 

https://wiki.qt.io/Exporting_a_document_to_PDF  


#1 QTextDocument 를 생성하고 html 코드를 넣어준다.

QTextDocument doc;

doc.setHtml("<h1>Hello, World!2222</h1>\n<p>Lorem ipsum dolor sit amet, consectitur adipisci elit</p>");
//doc.setHtml(docString);

doc.setPageSize(printer.pageRect().size()); // This is necessary if you want to hide the page number


#2-1 생성한 doc를 가지고 pdf 저장하기.

QPrinter printer(QPrinter::PrinterResolution);
printer.setOutputFormat(QPrinter::PdfFormat);
printer.setPaperSize(QPrinter::A4);
printer.setOutputFileName(fileName);

doc.print(&printer);


#2-2 생성한 doc를 가지고 인쇄하기

QPrinter printer;
QPrintDialog popup(&printer);
if (popup.exec() == QDialog::Accepted) //인쇄 설정창에서 확인을 하면
{
    doc.print(&printer); //인쇄를 한다.
}




by 무위자연 2019.02.20 15:25

관련 애플 문서 : https://developer.apple.com/documentation/foundation/userdefaults 

object c 사용 포스팅 : http://bmwe3.tistory.com/1725?category=682591 

예는 array

<저장하기>

 if var keywordList = UserDefaults.standard.array(forKey: keywordField) as? [String] {

            keywordList.insert(keyword, at: 0)

            if(keywordList.count > 5)

            {

                keywordList.remove(at: 5)

            }

            UserDefaults.standard.set(keywordList, forKey: keywordField)

        }

        else {

            var newList = [String]()

            newList.append(keyword)

            UserDefaults.standard.set(newList, forKey: keywordField)

        }


<get / 꺼내쓰기>

 return UserDefaults.standard.array(forKey: keywordField) as! [String]

by 무위자연 2019.01.12 11:16

여러 개의 조건을 선택적으로 적용하는 NSPredicate를 작성하는 방법


let predicateNotebookId = NSPredicate(format: "relatedNotebookId = %@", NSNumber(value: self.selectedNoteBookId)) // basic NSPredicate

 var predicateList = [NSPredicate]()//여러 조건을 추가할 list

  predicateList.append(predicateNotebookId)


   if(self.searchText_ != "")//추가 조건 #1

   {

             let predicateSearch = NSPredicate(format: "title contains %@ OR content contains %@", self.searchText_, self.searchText_)

predicateList.append(predicateSearch)

 }

        

  if(self.button_searchByAlarm.isSelected == true)//추가 조건 #2

   {

            let predicateAlarm = NSPredicate(format: "alarmDate != nil ")

            predicateList.append(predicateAlarm)

    }

        

    let andPredicate:NSCompoundPredicate = NSCompoundPredicate(type: .and, subpredicates: predicateList)

여러 조건을 적용하여  사용한다.



by 무위자연 2019.01.12 10:12
#0 이직 : 아이센스 > 메디트
내년엔 개발자로서 더 성장해야지!!

이전 :
분석화학 중심의 의료기기 제조사
리더도 비전도 없는 조직/
소수 IT개발자 그룹/
체계 없이(기획, 디자이너, PM? 사람도 단계도 없이 영업 관련자 몇명 구두지시로 대부분....) 작은 프로젝트를 4-5개 진행하던 것- rails, mfc, WPF, qt, swift, objective c...
잦은 출장과 개발 이외에 많은 업무(병원 관계자, 영업업체(H모), 납품업체 와 커뮤니케이션을 포함한)/
넘치는 사내 정치와 꼰대들/
3-5호선 이용한 왕복 3시간 출퇴근 시간

현재 :
3D스캐너가 중심인 의료기기 제조사
멋진 리더와 비전이 공유 되는 조직/
체계화된 IT개발 그룹 내에서 큰 프로젝트를 하나 하는 것 - only qt
앉아서 개발만개발만~
5-6호선을 이용한 왕복 2시간 출퇴근 시간

*일반적인 회사원의 겪어야 하는 공통 애로 사항은 제외함~

#1 본격적인 토이프로젝트 진행의 생활화.
git 2016 : 1  / 2017 : 23 / 올해는 170?


#2 규칙적인 인강생활
<수강중>
Autolayout 완벽가이드 - 실무프로젝트를 위한 실전강의(인프런)
자바 스크립트로 알아보는 함수형 프로그래밍(인프런)

<수강 완료한 것>
웹 개발 풀 스택 - Rails부분만 재수강함.(인프런)
ios 개발 - 야곰님(edwith)
sublimetext 3 마스터링 코스(인프런)
신입프로그래머를 위한 자바 스프링(spring)(인프런)
신입프로그래머를 위한 실전 JSP(인프런)
실전 자바(인프런)

*하나빼고 인프런이네..인프런덕후인가 난 ㅠ

#3 연차를 내서라도 세미나 참석하는 용기를 내어봄
Swift 세미나 참석 - http://bmwe3.tistory.com/1740 

#4 개발 요소에 대한 posting - 10개(qt 8, c++ 1, wpf 1)


by 무위자연 2018.12.31 10:38

circle 안에 이미지가 들어가는 형태를 구현하기가 생각보다 어렵고.


고정된 이미지일 경우 style sheet로 간단하게 구현이 된다.


하지만 로컬 이미지를 가지고? circle 형태의 QLabel을 만들기는 까다롭다



그래서 QLabel를 상속 받아서 다음과 같이 처리하면 쉽게? 그릴수 있다.

CircleLabel은 QLabel을 상속 받은 QWidget이다.

private:

void paintEvent(QPaintEvent *event) override;//paintEvent을 override한다


void CircleLabel::paintEvent(QPaintEvent *event)

{

QString pixmapPath = imagePath_;

if (imagePath_.isEmpty())

{

pixmapPath = ":image/defaultimage.png";

}

//draw main image

QPixmap mainPixmap(pixmapPath);

QPixmap scaled = mainPixmap.scaled(width(), height(), Qt::KeepAspectRatioByExpanding,                 Qt::SmoothTransformation);

QBrush brush(scaled);

QPainter painter(this);

painter.setRenderHint(QPainter::Antialiasing, true);

painter.setRenderHint(QPainter::SmoothPixmapTransform, true);

painter.setBrush(brush);

painter.setPen(QColor("red"));//pen 색을 적절히 지정해주면 antialiasing이 부족한 부분이 티가 덜 난다~

painter.drawRoundedRect(0, 0, width(), height(), 90, 90);

//만일 2개 이미지를 겹쳐서 그린 다면 다음과 같이 추가해주면 된다.- 첨부이미지 기준으로 스머프 우측 하단에 //설정 이미지와 같은.~

QPixmap settingPixmap(":image/Edit.png");

painter.drawPixmap(66, 66, settingPixmap);


QLabel::paintEvent(event);

}

by 무위자연 2018.12.10 11:40