Russian Qt Forum
Ноябрь 22, 2024, 03:59 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало Форум WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  
  Просмотр сообщений
Страниц: [1]
1  Qt / Вопросы новичков / Сторонняя подключенная библиотека не работает : Сентябрь 25, 2024, 12:53
Добрый день. Создаю проект, в котором нужно будет общаться с hid-устройством, чтобы контролировать зажигающиеся светодиоды. Сама я со сторонними библиотеками дело не имела, потому длительное изучение данной темы привело меня на небезызвестную (судя по ее упоминаниям) библиотеку hidapi с github'а. Саму библиотеку я скомпилировала, как было написано в README для WINDOWS на Visual studio, создала .dll, .lib файлы, стала подключать ее к проекту, который я пока не разбирала, но пример которого был взят с другого сайта, чтобы просто проверить хотя бы подключение библиотеки, не говоря уже о работе.
Подключала я ее следующим образом:
keykey.pro
Код:
QT -= gui
 
CONFIG += c++11 console
CONFIG -= app_bundle
 
# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
 
# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#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
 
INCLUDEPATH += $$PWD/.
LIBS += -L$$PWD/./ -lhidapi

main.cpp
Код:
#include <QCoreApplication>
 
#include <stdio.h>
#include <wchar.h>
#include <string.h>
#include <stdlib.h>
#include "hidapi.h"
#include <unistd.h>
 
#define MAX_STR 255
 
int main(int argc, char *argv[])
{
    //QCoreApplication a(argc, argv);
    //return a.exec();
 
 
    int res;
    unsigned char buf[256];
 
    wchar_t wstr[MAX_STR];
    hid_device *handle;
    int i;
 
 
    struct hid_device_info *devs, *cur_dev;
 
    if (hid_init())
        return -1;
 
        devs = hid_enumerate(0x0, 0x0);
        cur_dev = devs;
        while (cur_dev) {
            printf("Device Found\n  type: %04hx %04hx\n  path: %s\n  serial_number: %ls", cur_dev->vendor_id, cur_dev->product_id, cur_dev->path, cur_dev->serial_number);
            printf("\n");
            printf("  Manufacturer: %ls\n", cur_dev->manufacturer_string);
            printf("  Product:      %ls\n", cur_dev->product_string);
            printf("  Release:      %hx\n", cur_dev->release_number);
            printf("  Interface:    %d\n",  cur_dev->interface_number);
            printf("\n");
            cur_dev = cur_dev->next;
        }
        hid_free_enumeration(devs);
 
        // Set up the command buffer.
        memset(buf,0x00,sizeof(buf));
        buf[0] = 0x01;
        buf[1] = 0x81;
 
 
        // Open the device using the VID, PID,
        // and optionally the Serial number.
        ////handle = hid_open(0x4d8, 0x3f, L"12345");
        handle = hid_open(0x4d8, 0x3f, NULL);
        if (!handle) {
            printf("unable to open device\n");
            return 1;
        }
 
        // Read the Manufacturer String
        wstr[0] = 0x0000;
        res = hid_get_manufacturer_string(handle, wstr, MAX_STR);
        if (res < 0)
            printf("Unable to read manufacturer string\n");
        printf("Manufacturer String: %ls\n", wstr);
 
        // Read the Product String
        wstr[0] = 0x0000;
        res = hid_get_product_string(handle, wstr, MAX_STR);
        if (res < 0)
            printf("Unable to read product string\n");
        printf("Product String: %ls\n", wstr);
 
        // Read the Serial Number String
        wstr[0] = 0x0000;
        res = hid_get_serial_number_string(handle, wstr, MAX_STR);
        if (res < 0)
            printf("Unable to read serial number string\n");
        printf("Serial Number String: (%d) %ls", wstr[0], wstr);
        printf("\n");
 
        // Read Indexed String 1
        wstr[0] = 0x0000;
        res = hid_get_indexed_string(handle, 1, wstr, MAX_STR);
        if (res < 0)
            printf("Unable to read indexed string 1\n");
        printf("Indexed String 1: %ls\n", wstr);
 
        // Set the hid_read() function to be non-blocking.
        hid_set_nonblocking(handle, 1);
 
        // Try to read from the device. There shoud be no
        // data here, but execution should not block.
        res = hid_read(handle, buf, 17);
 
        // Send a Feature Report to the device
        buf[0] = 0x2;
        buf[1] = 0xa0;
        buf[2] = 0x0a;
        buf[3] = 0x00;
        buf[4] = 0x00;
        res = hid_send_feature_report(handle, buf, 17);
        if (res < 0) {
            printf("Unable to send a feature report.\n");
        }
 
        memset(buf,0,sizeof(buf));
 
        // Read a Feature Report from the device
        buf[0] = 0x2;
        res = hid_get_feature_report(handle, buf, sizeof(buf));
        if (res < 0) {
            printf("Unable to get a feature report.\n");
            printf("%ls", hid_error(handle));
        }
        else {
            // Print out the returned buffer.
            printf("Feature Report\n   ");
            for (i = 0; i < res; i++)
                printf("%02hhx ", buf[i]);
            printf("\n");
        }
 
        memset(buf,0,sizeof(buf));
 
        // Toggle LED (cmd 0x80). The first byte is the report number (0x1).
        buf[0] = 0x1;
        buf[1] = 0x80;
        res = hid_write(handle, buf, 17);
        if (res < 0) {
            printf("Unable to write()\n");
            printf("Error: %ls\n", hid_error(handle));
        }
 
 
        // Request state (cmd 0x81). The first byte is the report number (0x1).
        buf[0] = 0x1;
        buf[1] = 0x81;
        hid_write(handle, buf, 17);
        if (res < 0)
            printf("Unable to write() (2)\n");
 
        // Read requested state. hid_read() has been set to be
        // non-blocking by the call to hid_set_nonblocking() above.
        // This loop demonstrates the non-blocking nature of hid_read().
        res = 0;
        while (res == 0) {
            res = hid_read(handle, buf, sizeof(buf));
            if (res == 0)
                printf("waiting...\n");
            if (res < 0)
                printf("Unable to read()\n");
            usleep(500*1000);
        }
 
        printf("Data read:\n   ");
        // Print out the returned buffer.
        for (i = 0; i < res; i++)
            printf("%02hhx ", buf[i]);
        printf("\n");
 
        hid_close(handle);
 
        /* Free static HIDAPI objects. */
        hid_exit();
 
        return 0;
}

Но у меня везде, где упоминаются методы из библиотеки показывается сообщение такого вида: undefined reference to `hid_init'

Все файлы у меня находятся в одной папке и имеют следующий вид:
keykey:
| hidapi.dll
| hidapi.h
| hidapi.lib
| keykey.pro
| main.cpp

Помогите, пожалуйста, разобраться, в чем проблема. Я уже множество разных методов перепробовала: и указывать в либсе .dll, и указывать .lib, и располагать файлы в друих местах. Но что интересно, если я на F2 буду переходить по ссылкам относительно какой-то функции, то меня отправляет в файл "hidapi.h" без каких-то проблем.
Заранее извиняюсь за мое невежество: в интернете много новой и сложной для меня информации, поэтому могу жёстко "косячить"...
2  Qt / Вопросы новичков / Re: Не отвечает слот после отправки сигнала : Июль 24, 2024, 10:28
выше тебе все правильно написали. Тебе нужно передать autw в объект ld (например, как параметр конструктора), а не создавать внутри load новый объект Automat.
Ну, перенесу я таким способом autw, но у меня же load.cpp не будет знать, кто это такой. Объект ld создан и находится же в mainwindow, а коннекты же прописаны в файле load.cpp, то есть у них не будет прямой связи. Разве не так?
П.с. Скорее всего, не так, но я не понимаю, как объявленный объект в конструкторе поможет объявить коннекты в другом файле. Или его надо прописывать не так, как ниже, а именно в конструкторе класса load?
mainwindow.cpp
Код:
...
autw = std::make_unique<Automat>();
ld = std::make_unique<load>(autw);
...
3  Qt / Вопросы новичков / Re: Не отвечает слот после отправки сигнала : Июль 23, 2024, 13:49
Потому что разные экземпляры Automat инициированы для разных переменных autw
Покажусь глупой, но они же и должны быть разными, или нет..?
По сути, да, они разные и друг друга не знают, потому что один в mainwindow находится, а второй - в load. Первый открывает (по сути) вторую вкладку, а второй должен заполнять текст.
А если они должны быть в виде единственного экземпляра, то как это указать в двух разных файлах? Не совсем понимаю, на то ли я вообще тогда опираюсь
 
залей пожалуйста код в виде zip или 7z архива, у меня нет возможности открыть rar. Про rar надо уже давно забыть и отправить на свалку истории.
Вот, с уже исправленными на unique_ptr: https://disk.yandex.ru/d/5BjKJRV7hcyaBw
4  Qt / Вопросы новичков / Re: Не отвечает слот после отправки сигнала : Июль 23, 2024, 10:10
сигнал take_free_pallet случайно не из конструктора Automatic испускается? это бы объяснило почему слот не вызывается.
Не, он испускается не из конструктора - там вызывается метод отдельно, где уже и инспускается сигнал

ну или объект automatic_wind удаляется рано. Больше проблем вроде не видно.
Вот тут не уверена, что удаляется, вроде объект automatic_wind не удаляется в данный момент (по крайне мере, в бэбаггере он есть..).

Я пыталась разобраться сама с этим, сделала мини-приложение, которое плюс-минус напоминает механизм исходной программы (так как там уж слишком много всего...).
Вот оно: https://disk.yandex.ru/d/oUMQTPvJmbbJpw
Я обнаружила, что если у меня стоят коннекты в файле load, то сигнал и слот на работают, а если я его переставляю в auto, то все срабатывает без проблем. В чем тут может быть проблема? Я читала, что сигналы и слоты соединяются в определенных .h-файлах, но я ничего не смогла путного там разобрать...

П.С. В самом мини-приложении суть такова: есть первая страница, по нажатии на "3" я перехожу на вторую страницу, а на второй при нажатии на "1" или "2" должен появляться свой текст, вот в тексте проблема и оказалась - он просто не появляется. При перестановке коннекта все работает правильно.
5  Qt / Вопросы новичков / Не отвечает слот после отправки сигнала : Июль 09, 2024, 10:18
Добрый день. Такая странная проблема нарисовалась: я делала сигнал и слот (как обычно это делаю) для двух файлов, но я не могу понять, почему функция слота не работает, будто вообще не вызывается. Буду благодарна, если подскажите, а то уже весь мозг сломала... Все другие сигналы и слоты с файлом Automatic работают хорошо, а тут вобще не выходит. При работе вызываемой функции должно появиться сообщение в дэбаггере, а его нет, то есть строки кода не выполняются.
Вот отрывки моего кода:

automatic.cpp
Код:
...
public slots:
    void free_pallet(QVector<int> to_free_pallet);
 
signals:
    void take_free_pallet();    //сигнал базе данных на считывание свободных мест


database.h
Код:
#include <automatic.h>
...
private:
    Automatic *automatic_wind;
 
signals:
    void send_free_pallet(QVector<int>);
 
public slots:
    void search_free_pallet();


automatic.cpp
Код:
...
    //проверка:
    emit take_free_pallet();
    qDebug()<<"signal on automatiic";
...


database.cpp
Код:
DataBase::DataBase(QObject *parent) : QObject(parent)
{
    qDebug()<<"it work";
 
    automatic_wind = new Automatic();
    connect(automatic_wind,&Automatic::take_free_pallet,this,&DataBase::search_free_pallet);
    connect(this,&DataBase::send_free_pallet,automatic_wind,&Automatic::free_pallet);
}
...
void DataBase::search_free_pallet(){
    qDebug()<<"search";
    QVector <int> number_pallet;
    QSqlQuery *query = nullptr;
    ...
    emit send_free_pallet(number_pallet);
    qDebug()<<"signal on database";
}

Получается, что у меня вообще не вызыватся метод search_free_pallet() в классе DataBase, после того, как я посылаю сигнал take_free_pallet() в Automatic. Не знаю, как проверить, посылает от там что-то или нет (по ощущению будто нет).
Страниц: [1]

Страница сгенерирована за 0.064 секунд. Запросов: 24.