Qt Console Application을 만들고 Run을 시켰는데 Console 창이 안뜨고 아래 Application Output Pannel에 결과가 나오는 경우가 있습니다.
QT -= gui
CONFIG += c++17 console
CONFIG -= app_bundle
# You can make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += \
main.cpp
# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target
보안이나 특정 상황에 의해서 외부망에 연결하지 않는 내부 서버들이 있습니다. 이럴 경우 시간 동기화에 문제가 발생할 수 있는데 윈도우 NTP 서버 / 클라이언트 기능을 이용하여 위 문제를 해결할 수 있습니다. 하지만 이 해결 방법은 하나의 인터넷에 연결된 서버가 같은 망에 적어도 1개는 존재해야 가능합니다.
구성은 아래와 같습니다. 외부망과 연결된 서버는 time.windows.com 같은 Time Server와 시간을 동기화 해주고 그 동기화 된 시간을 내부서버가 Windows NTP 기능을 이용해 다시 동기화 합니다.
먼저 외부와 연결된 서버에 설정을 해줍니다.
[Windows 방화벽] > [고급 설정] > [인바인드 규칙] > [새 규칙] 으로 들어가 규칙을 추가합니다.
NTP의 경우 123번 포트 사용합니다.
[Win] + [R] 으로 실행을 실행해서 gpedit.msc를 입력해 로컬 그룹 정책 편집기를 실행합니다.
[Windows 시간 서비스] > [글로벌 구성 설정] 에서 AnnounceFlags를 5로 설정합니다.
실행에서 services.msc을 입력해 서비스를 실행합니다.
Windows Time을 클릭 후 시작 유형을 자동으로 바꾼 후 시작을 눌러줍니다.
다음으로 내부 서버 설정입니다.
실행에서 regedit.exe를 입력해 레지스트리 편집기를 실행 후 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W32Time\TimeProviders\NtpClient\SpecialPollInterval 값을 원하시는 동기화 주기로 입력합니다. (초 단위)
실행에서 services.msc를 입력해 서비스를 실행 후 Windows Time의 시작 유형을 자동(지연된 시작)으로 설정 후 시작합니다.
마지막으로 Windows 시간에서 [날짜 및 시간 설정 변경] > [날짜 및 시간] > [인터넷 시간] > [설정 변경]을 클릭합니다.
이제 설정한 서버의 IP를 입력 후 지금 업데이트를 통해 테스트 후 확인을 눌러 설정을 마무리 합니다.
기존에 설치된 Qt를 재설치 했더니 Qt5 버전에서 Quick Applicaiton Create가 안되는 증상이 있었습니다. 확인해보니 Qt Creator 10.0을 설치하면 Build System에 qmake가 없는 증상이 있고 그렇기 때문에 project를 생성할 수 없었습니다.
해당 문제를 해결하기 위해 Qt Creator 9.0으로 다운그레이드 하여 사용하겠습니다. 아래 링크를 통해 Qt Creator를 재설치 해줍니다.
이번에는 model 자체를 C++ 객체를 통해 가져와보겠습니다. C++ 쪽 클래스는 QAbstractListModel을 상속받는 Model 클래스와 그 클래스를 가지고 있는 Manager 클래스를 만들겠습니다. qml의 ListView는 이 Manager 함수를 통해 Model을 관리하게 됩니다.
위 설명대로 nameList에서는 model로 ModelMgr을 통해 MDataModel을 받고 있습니다. 그리고 input, delete도 ModelMgr을 통해 Model에 접근하고 있습니다.
main.qml 측에서는 MDataModel 클래스에 대한 정보가 없기 때문입니다. 이를 위해서 qmlregistertype를 통해서 등록시켜줘야 합니다. 추가로 qml에서 ModelMgr의 함수를 호출할 것이기 때문에 setContextProperty를 통해 넘겨줍니다.
qmlRegisterType를 통해 객체를 등록했으면 qml 에서는 import 시켜줄 수 있습니다.
import QtQuick 2.15
import QtQuick.Window 2.15
import DataModel 1.0
Window {
property int listViewheight : ModelMgr.count * dataHeight;
property int dataHeight : 50;
property int inputUIHeight : 30;
property int columnSpacing : 10;
...
}
다음은 ModelMgr 클래스입니다. 이 클래스는 QAbstractListModel을 상속받은 클래스를 변수로 가지고 있고 qml에서 add, remove 시에 Model에 전달해주기 위한 클래스입니다. count를 통해 listView의 크기를 동적으로 조절하기 위해 Q_PROPERTY로 설정하고 add, remove 시 countChanged signal을 발생시키고 있습니다.
여기서 Binding은 target(갱신할 대상)에 mainLoader의 item의 backColor Property를 지정하고 있습니다. 여기서 이 property에 넣어줄 값은 TextField가 가지고 있는 text 값입니다. 이렇게 설정해 주면 TextField의 값을 변경할 때마다 매번 set 해주지 않아도 됩니다.
만약 binding을 사용하지 않고 TextField의 Signal을 이용한다면 Loader의 source가 바뀔 때는 제대로 적용이 되지 않습니다.