2026년 4월 24일 금요일

아발로니아 초기 스케폴딩

[아발로니아 설치]
dotnet new install Avalonia.Templates



[아발로니아 mvvm 프로젝트 만들기 현재폴더에]
dotnet new avalonia.mvvm -n 프로젝트이름 -o .


[타겟빌드가 닷넷 8.0 이라면]

*.cjproj 파일에서 아래의 부분을 net8.0 으로 변경
<TargetFramework>net8.0</TargetFramework>


이후 
dotnet clean
dotnet restore




[App.axaml.cs 파일 초기설정]

//
public partial class App : Application
{
    /// <summary>
    /// 초기화
    /// </summary>
    public override void Initialize()
    {
        AvaloniaXamlLoader.Load(this);
    }

    /// <summary>
    /// 프레임워크 초기화됨
    /// </summary>
    public override void OnFrameworkInitializationCompleted()
    {
        //초기화 처리
        OnLoad();
        
        //메인프레임 생성
        if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
        {
            desktop.Exit += OnExit;
            desktop.MainWindow = new MainWindow();
        }
        //
        base.OnFrameworkInitializationCompleted();
    }

    /// <summary>
    /// 초기화 구문
    /// </summary>
    public void OnLoad()
    {
    }

    /// <summary>
    /// 종료처리 = (Application.Current?.ApplicationLifetime as IClassicDesktopStyleApplicationLifetime).Shutdown(0); 
    /// </summary>
    public void OnExit(object? sender, EventArgs e)
    {
    }

}

2026년 4월 23일 목요일

닷넷으로 개발할때 git 설정처리

닷넷을 개발할때 vs말고  vscode나 라이더에서 개발할때

깃저장소 초리기 방법 (커맨드창 개별관리가 좋으다.)

처음에 솔루션 파일(*.sin) 이 있는 폴더에서

git init .

이후

dotnet new gitignore

로 이그노어 파일생성

git remote -v

로 원격지 연결 확인하고 없으면

git remote add origin [원격지 주소]

혹시 먼저 땡겨와야한다면 (풀링)

git pull origin main

이후에 하던데로

git add . -> git comm .....  쭉 이어나가면 됨..

2026년 4월 21일 화요일

새로운 시작을 응원하며..

작은 새는 오랜 시간 거미줄에 묶여 날갯짓하는 법조차 잊어버린 듯 보였습니다. 하지만 관찰자가 묵묵히 지켜보며 건네준 진실의 순간들은, 새가 마지막 힘을 내어 거미줄을 끊어내는 도구가 되었습니다. 이제 숲을 떠난 새는 더 이상 포식자의 눈물을 보지 않아도 됩니다. 그곳에는 오직 자신의 날개 소리와 자유로운 바람만이 존재할 뿐입니다.

2026년 4월 18일 토요일

파이썬 GUI 환경 곁다리로 배포하기

예전에 mfc나 윈폼으로 메시지 드리븐 기반의 GUI 프로그래밍을 해오던 경험을
해온 나는 GUI라는것이 명령기반으로만 생각을 해왔다..

그러다가 안드로이드가 나왔고 xml기반의 뷰드로잉이 희안하다고 생각했고
플러터가 나와서 메서드 체이닝식 랜더링을 보면서 더이상 디자인에 대한 부분이 
명령기반이 아닌 분리되어 랜더링되게 만들어야 한다는 생각으로 바뀌었다.

그래서 아발로니아 같은것을 다루면서 이런 생각이 완전히 바뀌었다.
헌데.. 이런 구조를 처리할때는 디자인 패턴이라는것이 중요하다 MVVM이나 
DI 뷰협상 이런것들..
그런데 이런것들은 당연히 좋은데 빨리 뭔가를 GUI로 만들고 싶어하는 상황에서는
이러한 아키텍쳐가 오히려 에너지를 빼는 일이 되어 버릴 수 있다..

이상황에서는 드레그 드롭방식으로 뷰를 만들고 명령기반 코딩방식이 유의미 
할것이다. 헌데 나한테는 이 윈폼이 좋기는한데 뭔가 인스턴스 적인 느낌이 
없달까?? 이런 느낌이다. 빌드도 해야하고 요즘에는 실행시 런타임도 깔아야한다.

해서 이 중간 어디쯤을 커버칠수 있는부분을 찾다가 PyQt에 머무르게 되었다.
파이썬도 GUI라고 하면 tkinter, wxpython, kivy 이런것들이 많다..
하지만 지금에 와서는 디자이너가 있고 파일로 분리되는 깔끔함은 사실상 PyQt로
대동단결 되는 느낌이다.  tkinter에서 pack() 이런거 나열하고 있으면
디자인도 구린데 이렇게 까지 해야하나.. 이런 생각이 든다.
그래서 결론적으로 pyqt를 이용할 생각인데 이게 배포하는게 귀찮을 수 있다.
중간 어디쯤인 프로그램 답게 그냥 코드는 노출되어 상관이 없을것이고
콘솔은 사용자가 힘들게 접근할테니까.. 이 pyqt를 잘 배포하는것이 문제로 떠올랐다.


[본론으로 들어가서]

파이썬이 깔려있다는 전재하에 윈도우로 배포(이 개념이 리눅스도 먹힐것이다.) 한다고
가정하면 bat파일로 실행시킬때 가상환경인 venv폴더를 만들고 그때 reqlist.txt
파일을 읽어서 그 안의 내용을 pip install 처리하면 될것이다.
그리고 다음 실행시에는 그 vevn폴더가 있고 그 안에 installed.txt 파일이 설치완료를
말하고 있을테니 바로 실행하면 되겠다.  그리고 실행파일은 main.py이다.



- bat파일의 내용 -

@echo off
pushd "%~dp0"

if not exist "venv\installed.txt" (
    echo Ready for Launch..
    rmdir /s /q venv 2>nul
    python -m venv venv
    call venv\Scripts\activate

    python -m pip install --upgrade pip
    if exist "reqlist.txt" pip install -r reqlist.txt    
    echo OK > venv\installed.txt
) else (
    call venv\Scripts\activate
)

start pythonw main.py
exit



이렇게 작성해서 전달하면 GUI 기반으로 프로그램을 전달할수 있다.

아래는 main.ui 파일을 사용하는 기본 윈도우 프레임틀  
(QMainWindow의 minimumsize를 설정해주기 잊지마~)
(reqlist.txt 에는 기본적으로 PySide6 가 들어가 있어야겠쥬)


from PySide6.QtWidgets import *
from PySide6.QtUiTools import QUiLoader
from PySide6.QtCore import QFile
import sys

#
class MyApp(QMainWindow):
    def __init__(self):
        super().__init__()        
        #        
        loader = QUiLoader()
        file = QFile("main.ui")
        if file.open(QFile.ReadOnly):
            self.ui_content = loader.load(file)            
            self.setCentralWidget(self.ui_content)
            file.close()        
        
    # 종료 이벤트
    def closeEvent(self, event):
        QApplication.quit()
        event.accept()

#
if __name__ == "__main__":
    app = QApplication(sys.argv)
    window = MyApp()
    window.show()
    sys.exit(app.exec())


2026년 4월 16일 목요일

MSSQL 시간 관련 처리 쿼리

[시간 관련 함수]

현재시간    |    GETDATE() or SYSDATETIME()    |    현재시간을 추출함
형식변환(날짜)    |    CAST(GETDATE() as DATE)    |    '2026-04-17' 형태만 남김
형식변화(문자)    |    CONVERT(VARCHAR, GETDATE(), 120)    |    스타일로변환
시간차이    |    DATEDIFF(보간값, 전시간, 후시간)    |    두시간사이 차이를 보간으로 반환
시간더하기    |    DATEADD(보간값, 9, GETDATE())    |    특정 보간시간의 합산분처리
특정부분추출    |    DATEPART(보간값, GETDATE())    |    시간에서 보간값을 뽑아냄

※ 보간값: HOUR, MINUTE, SECOND ※


[Convert 스타일 번호] - Convert(Varchar(x), TimeColumn, StyleNumber)

없음    |    cast(dt as varchar)    |    Apr 17 2026 2:25PM
1번    |    mm/dd/yy    |    04/17/26
3번    |    dd/mm/yy    |    17/04/26
23번    |    yyyy-mm-dd    |    202-04-17
108번    |    hh:mm:ss    |    14:25:19
101번    |    mm/dd/yyyy    |    04/17/2026
110번    |    mm-dd-yyyy    |    04-17-2026
111번    |    yyyy/mm/dd    |    2026-04-17
112번    |    yyyymmdd    |    20260417
120번    |    yyyy-mm-dd hh:mm:ss    |    2026-04-17 14:25:19
121번    |    yyyy-mm-dd hh:mm:ss.fff    |    2026-04-17 14:25:19.000
126번    |    yyyy-mm-ddThh:mm:ss.fff    |    2026-04-17T14:25:19.000    


[기간조회 공식]

(SB <= PE && SE >= PB)


2026년 3월 25일 수요일

아발로니아 독립스텍

개쩌는 아발로니아 UI 12 출시기념으로 독립스텍을 만들었 드랬다.



계층 기술 스택 비고
프레젠테이션 Avalonia UI + Noto Sans KR 어떤 환경에서도 변치 않는 UI 가독성

비즈니스 로직 .NET 10.0 (C#) 강력한 타입 안정성과 최신 성능

데이터베이스 PostgreSQL (Npgsql) 엔터프라이즈급 쿼리 성능과 데이터 신뢰성

파일/미디어 ImageSharp, FFmpeg, EPPlus, QuestPDF 생성부터 편집, 출력까지 기기 내 완결

네트워크 SMBLibrary 윈도우 공유 폴더와의 유연한 연결성

2026년 2월 11일 수요일

닷넷으로 소형 리눅스 IOT기기의 아이피v4 변경 하기

요즘에는 라즈베리파이니 오렌지파이니 해서 소형 리눅스 디바이스가 활약하는 일이 잦아졌다.






sudo systemctl daemon-reload
sudo systemctl enable orange-net
sudo systemctl start orange-net