Programming/qt2026. 6. 30. 12:40

connect() 함수를 사용하면 대개 인자를 4개만 넣고 쓰는데

함수 프로토타입을 보니 가장 마지막 인자가 기본값으로 지정되어 있다.

// qobject.h
    static inline QMetaObject::Connection connect(const typename QtPrivate::FunctionPointer<Func1>::Object *sender, Func1 signal,
                                     const typename QtPrivate::FunctionPointer<Func2>::Object *receiver, Func2 slot,
                                     Qt::ConnectionType type = Qt::AutoConnection)

 

기본은 Qt:AutoConnection 이라는데 약간의 손실 가능성이 존재하고

반드시 손실되서는 안되는 경우라면 QueuedConnection으로 하는것을 추천한다고 한다.

// qnamespace.h
    enum ConnectionType {
        AutoConnection,
        DirectConnection,
        QueuedConnection,
        BlockingQueuedConnection,
        UniqueConnection =  0x80
    };

 

DirectConnection은 다른 스레드에서 쓰면 동기화 문제 발생할수 있다는걸 보면 동일 쓰레드 내에서 써야 할듯.

[링크 : https://still.tistory.com/86]

 

 

[링크 : https://doc.qt.io/qt-6/qt.html]

'Programming > qt' 카테고리의 다른 글

qt5 qml 다국어지원  (0) 2026.06.30
qt5 qml Q_PROPERTY  (0) 2026.06.30
qt5 qml connections  (0) 2026.06.30
qt 동적 해상도 대응  (0) 2026.06.29
QT 다국어 지원, qm 만 교체 할수 있도록 변경  (0) 2026.06.29
Posted by 구차니
Programming/qt2026. 6. 30. 12:31

언제나 그렇듯(?) tr() 대신 qsTr()로 감싸줘야 한다.

Text {
    id: txt1;
    text: qsTr("Back");
}

[링크 : https://doc.qt.io/archives/qt-5.15/qtquick-internationalization.html]

 

qt5.10 이전에는 retranslate()가 정상적으로 작동하지 않는 문제가 있었다고.

함수 레벨이 다름에 주의.

그런데.. installTranslator 하기 전에 removeTranslator 해줘야 하나?

    if(lang == "bg") {
     qApplication->removeTranslator(&trEN);
     qApplication->installTranslator(&trBG);
    } else if (lang == "en") {
     qApplication->removeTranslator(&trBG);
     qApplication->installTranslator(&trEN);
    }

    qmlEngine->retranslate();

[링크 : https://forum.qt.io/topic/90018/problem-with-dynamic-language-change-in-qml]

[링크 : https://wiki.qt.io/How_to_do_dynamic_translation_in_QML]

'Programming > qt' 카테고리의 다른 글

qt signal / slot, connect() Qt::AutoConnection  (0) 2026.06.30
qt5 qml Q_PROPERTY  (0) 2026.06.30
qt5 qml connections  (0) 2026.06.30
qt 동적 해상도 대응  (0) 2026.06.29
QT 다국어 지원, qm 만 교체 할수 있도록 변경  (0) 2026.06.29
Posted by 구차니
Programming/qt2026. 6. 30. 12:24

uml 외부와 내부를 연결해주려면 Q_PROPERTY를 이용해서 변수를 지정하고

해당 변수를 건드릴 함수를 연동해주면 된다.

class UIController : public QObject
{
    Q_OBJECT

    // ── 페이지 ──────────────────────────────────────────────
    Q_PROPERTY(int currentPage
               READ  currentPage
               WRITE setCurrentPage
               NOTIFY currentPageChanged)

    // ── 센서 / 데이터 값 ────────────────────────────────────
    Q_PROPERTY(double temperature
               READ  temperature
               NOTIFY temperatureChanged)

    Q_PROPERTY(double progress
               READ  progress
               NOTIFY progressChanged)

    // ── 텍스트 ──────────────────────────────────────────────
    Q_PROPERTY(QString statusText
               READ  statusText
               NOTIFY statusTextChanged)

[링크 : https://doc.qt.io/qt-6/qtqml-cppintegration-exposecppattributes.html]

 

다만 Q_PROPERTY로 연결이 가능한 타입에는 제한이 있다.

개인이 만든 구조체 등은 못 넘기는 듯?

[링크 : https://doc.qt.io/qt-6/qtqml-cppintegration-data.html]

'Programming > qt' 카테고리의 다른 글

qt signal / slot, connect() Qt::AutoConnection  (0) 2026.06.30
qt5 qml 다국어지원  (0) 2026.06.30
qt5 qml connections  (0) 2026.06.30
qt 동적 해상도 대응  (0) 2026.06.29
QT 다국어 지원, qm 만 교체 할수 있도록 변경  (0) 2026.06.29
Posted by 구차니
Programming/qt2026. 6. 30. 11:39

claude에게 qt5 qml 예제를 만들어 달라고 하고  코드 분석중

이전에는 못봤던 Connections 라는 키워드가 눈에 띈다

// Main.qml
ApplicationWindow {
    id: root

    // uiController.currentPage 변화 → StackLayout 전환
    Connections {
        target: uiController
        // Qt5(Qt5.4+)는 함수형 핸들러 onXxxChanged 동일하게 지원
        onCurrentPageChanged: {
            stack.currentIndex = uiController.currentPage
        }
    }

    ColumnLayout {
        anchors.fill: parent
        spacing: 0
        // ── 페이지 스택 (StackedWidget 대응) ──────────────
        StackLayout {
            id: stack
            Layout.fillWidth: true
            Layout.fillHeight: true
            currentIndex: 0

            Loader { source: "HomePage.qml" }
            Loader { source: "DataPage.qml" }
            Loader { source: "SettingsPage.qml" }
        }

 

engine 에다가 setContextProperty 하는건 engine.load() 이후에 해도 적용되긴 한다.

// main.cpp
    // ── 인스턴스 생성 ─────────────────────────────────────
    SocketClient  socketClient;
    UIController  uiController;

    // ── 소켓 → UI 컨트롤러 시그널 연결 ───────────────────
    QObject::connect(&socketClient, &SocketClient::pageChangeRequested,
                     &uiController,  &UIController::onPageChange);

    QObject::connect(&socketClient, &SocketClient::valueChangeRequested,
                     &uiController,  &UIController::onValueChange);

    QObject::connect(&socketClient, &SocketClient::textChangeRequested,
                     &uiController,  &UIController::onTextChange);

    // ── QML 엔진 설정 ─────────────────────────────────────
    QQmlApplicationEngine engine;

    // QML에서 'socketClient', 'uiController' 이름으로 접근 가능
    engine.rootContext()->setContextProperty("socketClient", &socketClient);
    engine.rootContext()->setContextProperty("uiController", &uiController);

 

// socketclient.h
class SocketClient : public QObject
{
    Q_OBJECT
    Q_PROPERTY(bool connected READ isConnected NOTIFY connectedChanged)
    Q_PROPERTY(QString clientAddress READ clientAddress NOTIFY clientAddressChanged)

public:
    explicit SocketClient(QObject *parent = nullptr);
    ~SocketClient();

    bool isConnected() const { return m_socket != nullptr; }
    QString clientAddress() const { return m_clientAddress; }

    Q_INVOKABLE void startListening(int port = 9000);
    Q_INVOKABLE void stopListening();

signals:
    void connectedChanged();
    void clientAddressChanged();

    // 파싱된 명령 시그널
    void pageChangeRequested(int index);

 

// uicontroller.cpp
void UIController::setCurrentPage(int page)
{
    if (m_currentPage == page) return;
    m_currentPage = page;
    emit currentPageChanged();
}

void UIController::onPageChange(int index)
{
    setCurrentPage(index);
}

 

[링크 : https://swjs.tistory.com/entry/QTQML-QML의-Connections]

[링크 : https://doc.qt.io/qt-6/ko/qml-qtqml-connections.html]

'Programming > qt' 카테고리의 다른 글

qt5 qml 다국어지원  (0) 2026.06.30
qt5 qml Q_PROPERTY  (0) 2026.06.30
qt 동적 해상도 대응  (0) 2026.06.29
QT 다국어 지원, qm 만 교체 할수 있도록 변경  (0) 2026.06.29
QGraphicsProxyWidget  (0) 2026.06.05
Posted by 구차니
개소리 왈왈/컴퓨터2026. 6. 30. 10:23

일요일 부터 버려진 컴퓨터가 h81 이길래 그냥 주울 생각을 안하다가

오늘 혹시나 해서 cpu만 적출해볼까 하면서 열어보니 오오~!

 

다행히 잘 켜진다 ㅋㅋ

써멀 없이 그냥 쿨러만 달아서 온도가 어우

'개소리 왈왈 > 컴퓨터' 카테고리의 다른 글

포맷할때가 되었나..  (0) 2026.06.19
iptime as 접수  (0) 2026.06.15
asrock B360M pro4  (0) 2026.05.01
지름 - 케이스, 램  (0) 2026.04.30
되는게 없네 ㅋㅋㅋ - 라이트 컴 NA210  (0) 2026.04.30
Posted by 구차니

우회전 하는데 맞은편 좌회전이 너무 내쪽으로 붙어서

그걸 피한다고 이르게 회전했더니 뒷 타이어 연석에 긁어 먹었다.

제법 충격이 커서 tpms 바로 확인ㅇ하는데 공기압은 문제가 없어서 일단은 운행했는데

내리고 나서 확인해보니 제법 크고 깊게 찢어졌다.

 

그냥 보기에는 살짝이네~ 싶지만

 

들어서 보면 제법 깊게 파였다 ㅠㅠ

'개소리 왈왈 > 육아관련 주저리' 카테고리의 다른 글

베란다 문 잠금장치 수리  (2) 2026.06.23
바쁜주말  (2) 2026.05.31
밀크티 타블렛(s6 lite) 초기화 하기  (0) 2026.05.23
고향  (0) 2026.05.03
유류비 지원 때문인가?  (0) 2026.05.01
Posted by 구차니
embeded/robot2026. 6. 29. 18:09

atom 이랑 팔에 힘빼는거(!) 테스트

 

from pymycobot.mycobot import MyCobot
from pymycobot import PI_PORT, PI_BAUD
mc = MyCobot(PI_PORT, PI_BAUD)
mc.set_color(0,0,255)
mc.get_digital_input(39) # atom 누르지 않고
1
mc.get_digital_input(39) # atom 누르고
0
mc.power_off() # atom off
mc.get_digital_input(39) # atom 안 읽힘
mc.get_digital_input(39)
mc.power_on() # atom on
mc.get_digital_input(39) # atom 누르지 않고
1
mc.get_digital_input(39) # atom 누르고
0
mc.is_power_on()
1
mc.power_off()
mc.is_power_on()
0
mc.power_on()


mc.power_off()
mc.is_all_servo_enable()
mc.power_on()
mc.is_all_servo_enable()

 

power_on 은 atom(LED, 버튼 일체형) 통신 뿐만 아니라

servo 전원 on/off도 같이 엮인다.

1.1 power_on()     Function: Atom open communication (default open)
1.2 power_off()     Function: Atom turn off communication
1.3 is_power_on() Function: judge whether robot arms is powered on or not

 

서보(관절별) 잠그고, 푸는 명령

2.11 release_servo(servo_id) Function: release a servo
5.4 focus_servo(servo_id)    Function: power on designated servo

 

gpt 보고 짜달라니 잘 짜준다

#!/usr/bin/env python3

import curses
import time

from pymycobot.mycobot import MyCobot
from pymycobot import PI_PORT, PI_BAUD

# -------------------------------------------------
# myCobot
# -------------------------------------------------
mc = MyCobot(PI_PORT, PI_BAUD)

SPEED = 40
STEP = 2.0        # mm
ROT_STEP = 2.0    # degree

released = True

mc.power_on()
time.sleep(1)

coords = mc.get_coords()

if coords is None:
    print("Cannot read robot coordinates.")
    exit(1)


# -------------------------------------------------
def draw_screen(stdscr, angles):

    stdscr.clear()

    stdscr.addstr(0, 0, "myCobot 280 Jog Controller")

    stdscr.addstr(2, 0, "A/D : X -/+")
    stdscr.addstr(3, 0, "W/S : Y +/-")
    stdscr.addstr(4, 0, "R/F : Z +/-")
    stdscr.addstr(5, 0, "Q/E : RX -/+")
    stdscr.addstr(6, 0, "ESC : Exit")

    stdscr.addstr(8, 0, f"Servo : {'LOCK' if released else 'RELEASE'}")

    stdscr.addstr(
        10, 0,
        f"X={coords[0]:7.2f}  "
        f"Y={coords[1]:7.2f}  "
        f"Z={coords[2]:7.2f}"
    )

    stdscr.addstr(
        11, 0,
        f"RX={coords[3]:7.2f}  "
        f"RY={coords[4]:7.2f}  "
        f"RZ={coords[5]:7.2f}"
    )

    if angles is not None:
        stdscr.addstr(13, 0, "Joint Angles")

        for i, a in enumerate(angles):
            stdscr.addstr(14+i, 0, f"J{i+1}: {a:7.2f}")

    stdscr.refresh()


# -------------------------------------------------
def main(stdscr):

    global coords
    global released

    curses.cbreak()
    curses.noecho()

    stdscr.nodelay(True)
    stdscr.keypad(True)

    angles = mc.get_angles()

    draw_screen(stdscr, angles)

    while True:

        # ------------------------------------------
        # Atom Button
        # ------------------------------------------

        button = mc.get_digital_input(39)

        if button == 0 and released:

            released = False

            mc.release_all_servos()

            draw_screen(stdscr, angles)

        elif button == 1 and not released:

            released = True

            mc.power_on()

            time.sleep(0.5)

            # Servo를 손으로 움직였을 수 있으므로
            # 이때만 실제 좌표를 다시 읽음
            new_coords = mc.get_coords()
            if new_coords is not None:
                coords = new_coords

            angles = mc.get_angles()

            draw_screen(stdscr, angles)

        key = stdscr.getch()

        if key == 27:
            break

        moved = False

        if released:

            if key == ord('a'):
                coords[0] -= STEP
                moved = True

            elif key == ord('d'):
                coords[0] += STEP
                moved = True

            elif key == ord('w'):
                coords[1] += STEP
                moved = True

            elif key == ord('s'):
                coords[1] -= STEP
                moved = True

            elif key == ord('r'):
                coords[2] += STEP
                moved = True

            elif key == ord('f'):
                coords[2] -= STEP
                moved = True

            elif key == ord('q'):
                coords[3] -= ROT_STEP
                moved = True

            elif key == ord('e'):
                coords[3] += ROT_STEP
                moved = True

            if moved:
                mc.send_coords(coords, SPEED, 1)
                draw_screen(stdscr, angles)

        time.sleep(0.02)


# -------------------------------------------------
if __name__ == "__main__":
    curses.wrapper(main)

 

[링크 : https://docs.elephantrobotics.com/docs/gitbook-en/7-ApplicationBasePython/7.2_API.html]

'embeded > robot' 카테고리의 다른 글

왼손 오른손 좌표계  (0) 2026.06.22
mycobot280_pi urdf  (0) 2026.06.22
블루로봇 밸런스 스테이지  (0) 2026.06.21
elephant robotics cobot python api  (0) 2026.06.19
elephant robotics mycobot 280 pi python 예제  (0) 2026.06.16
Posted by 구차니
Programming/qt2026. 6. 29. 14:57

열심히 AI 갈구면서 테스트

 

아래의 클래스 추가

// UIScale.h
#pragma once

#include <QWidget>

namespace UIScale
{
    void scale(QWidget *w);
    void scaleTree(QWidget *root);
}

 

// UIScale.cpp

#include "UIScale.h"

#include <QGuiApplication>
#include <QScreen>
#include <QDebug>

namespace
{
    constexpr int BASE_WIDTH  = 800;
    constexpr int BASE_HEIGHT = 480;
}

void UIScale::scale(QWidget *w)
{
    if (!w)
        return;

    // 이미 적용했으면 종료
    if (w->property("_scaled").toBool())
        return;

    QScreen *screen = QGuiApplication::primaryScreen();
    if (!screen)
        return;

    QSize screenSize = screen->availableGeometry().size();

    const double sx = double(screenSize.width())  / BASE_WIDTH;
    const double sy = double(screenSize.height()) / BASE_HEIGHT;

    QRect r = w->geometry();

    w->setGeometry(
        int(r.x()      * sx),
        int(r.y()      * sy),
        int(r.width()  * sx),
        int(r.height() * sy));

    w->setProperty("_scaled", true);
}

void UIScale::scaleTree(QWidget *root)
{
    scale(root);

    const auto widgets = root->findChildren<QWidget *>();

    for (QWidget *w : widgets)
    {
        qDebug().noquote()
        << QString("%1")
              .arg(w->objectName());
        scale(w);
    }
}

 

해당 위젯의 showEvent()를 오버라이드 해서 사용한다.

scaleTree()만 실행해도 잘된다.(어짜피 tree에서 순회하면서 쭈욱 여는거라)

그런데 widget 들은 확대되서 잘 나오는데

stylesheet에서 background로 박아둔 녀석도 같이 확대되서 이상하게 작동하는 지라

스타일시트 엔진(?)은 따로 움직여서 손을 봐줘야 한다고.

void cycle::showEvent(QShowEvent *event)
{
    qDebug() << "helo";
    UIScale::scaleTree(this);
    this->update();
    this->repaint();

    QString ss = this->styleSheet();
    this->setStyleSheet("");
    this->setStyleSheet(ss);
}

[링크 : https://chatgpt.com/share/6a420896-c94c-83e8-9459-3c016987a64f]

'Programming > qt' 카테고리의 다른 글

qt5 qml Q_PROPERTY  (0) 2026.06.30
qt5 qml connections  (0) 2026.06.30
QT 다국어 지원, qm 만 교체 할수 있도록 변경  (0) 2026.06.29
QGraphicsProxyWidget  (0) 2026.06.05
QT 다국어 언어 설정 전파  (0) 2026.06.05
Posted by 구차니
Programming/qt2026. 6. 29. 10:49

현재 사용중인 코드는 좀 다르긴한데

잘 보면 :/i18n 으로 해서 리소스 파일에서 끌어오게 되어있다.

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);

    QTranslator myappTranslator;
    if (myappTranslator.load(QLocale::system(), u"myapp"_s, u"_"_s, u":/i18n"_s))
        app.installTranslator(&myappTranslator);

    return app.exec();
}

[링크 : https://doc.qt.io/qt-6/ko/i18n-source-translation.html]

 

그러면.. 이 경로만 바꾸어 주고 빌드 시스템에서

lrealse를 수동으로 해주면 이미지와 함께 배포하게 하면 충분히 하나로 합치지 않고 배포가 가능할 것 같긴한데..

 

빌드 디렉토리에서 i18n 으로 검색해보니 qrc 관련해서 우겨 넣는게 보인다.

$ grep -rn i18n .
grep: ./main.o: 바이너리 파일 일치함
./qrc_qmake_qmake_qm_files.cpp:3903:  // i18n
./qrc_qmake_qmake_qm_files.cpp:3963:  // :/i18n
./qrc_qmake_qmake_qm_files.cpp:3966:  // :/i18n/untitled_pt_PT.qm
./qrc_qmake_qmake_qm_files.cpp:3969:  // :/i18n/untitled_ko_KR.qm
./qrc_qmake_qmake_qm_files.cpp:3972:  // :/i18n/untitled_fr_FR.qm
./qrc_qmake_qmake_qm_files.cpp:3975:  // :/i18n/untitled_sk_SK.qm
./qrc_qmake_qmake_qm_files.cpp:3978:  // :/i18n/untitled_en_US.qm
./qrc_qmake_qmake_qm_files.cpp:3981:  // :/i18n/untitled_el_GR.qm
./qrc_qmake_qmake_qm_files.cpp:3984:  // :/i18n/untitled_ru_RU.qm
./qrc_qmake_qmake_qm_files.cpp:3987:  // :/i18n/untitled_es_ES.qm
./qmake_qmake_qm_files.qrc:2:<qresource prefix="i18n">

 

ts-files에 이름을 넣고 -qm에 생성될 파일을 넣으면되니까 어찌 되려나?

$ lrelease --help
Usage:
    lrelease [options] -project project-file
    lrelease [options] ts-files [-qm qm-file]

lrelease is part of Qt's Linguist tool chain. It can be used as a
stand-alone tool to convert XML-based translations files in the TS
format into the 'compiled' QM format used by QTranslator objects.

Passing .pro files to lrelease is deprecated.
Please use the lrelease-pro tool instead, or use qmake's lrelease.prf
feature.

Options:
    -help  Display this information and exit
    -idbased
           Use IDs instead of source strings for message keying
    -compress
           Compress the QM files
    -nounfinished
           Do not include unfinished translations
    -removeidentical
           If the translated text is the same as
           the source text, do not include the message
    -markuntranslated <prefix>
           If a message has no real translation, use the source text
           prefixed with the given string instead
    -project <filename>
           Name of a file containing the project's description in JSON format.
           Such a file may be generated from a .pro file using the lprodump tool.
    -silent
           Do not explain what is being done
    -version
           Display the version of lrelease and exit

[링크 : https://chatgpt.com/share/6a41cebb-e8bc-83ee-9207-6d9ef47ff0ca]

 

일단은.. 파일 validation을 넣고 실행하게 해야 안전할 것 같은데..

'Programming > qt' 카테고리의 다른 글

qt5 qml connections  (0) 2026.06.30
qt 동적 해상도 대응  (0) 2026.06.29
QGraphicsProxyWidget  (0) 2026.06.05
QT 다국어 언어 설정 전파  (0) 2026.06.05
QT 자식 위젯으로 생성 / 부모 위젯 연결  (0) 2026.06.05
Posted by 구차니

간단하게(?) 요약하면

기획서나 정의서에 "당연하다고 넘어가는 내용을 놓치지 않게" 잘 쓰고

 ai를 통해서 테스트 까지 할 수 있도록 사용해야 한다.

정도로 보인다.

예를 들어서 결제를 해라 정도로 쓰면

ai는 어떤 함수를 쓸지 알수 없기 때문에

최소한 어떤 모듈 어떤 함수로 결제를 어떤 조건에 해라 정도는 적으라는 듯.

[링크 : https://eopla.net/magazines/43902]

'개소리 왈왈 > 인공지능' 카테고리의 다른 글

새로운 마약 - AI  (0) 2026.03.17
agi를 느꼈다?  (0) 2026.02.24
바이브 코딩 ai 코딩의 광풍  (0) 2025.10.13
ai killed programmer  (0) 2025.05.23
chatGPT가 날로먹으려고 한다!!!!  (0) 2025.03.21
Posted by 구차니