在linux中使用蓝牙和qt

时间:2013-02-11 12:05:49

标签: qt bluetooth

我在C中编写了一个程序,通过蓝牙连接电脑和设备。程序从终端运行,接收的数据也显示在终端中。到目前为止一切都很好。

现在我在qt中创建了一个gui,其主要目的是显示之前在终端中显示的信息,现在是qwtplots。

好吧,到目前为止,我可以将设备与带有gui的pc连接,但是当我从设备请求信息时,它会显示在终端中,但是gui开始没有响应。

这是从设备请求信息的插槽:

// Main Bluetooth
void gui::main_b()
{
    // BLUETOOTH STUFF
    int status, bytes_read;
    int conta = 0;
    FILE *data = NULL;

    fd_set readmask;
    struct timeval tv;
    char buf[101];
    int v, v1, v2;

    tv.tv_sec = 0;
    tv.tv_usec = 100000;

    // Standard messages
    char *startstr = "@START,0060,FF,12;";

    write (sock, startstr, strlen (startstr));

    data = fopen ("data.txt", "w");
    while (conta < 100)
    {
        int i;
        memset (buf, 0, 100);
        FD_ZERO (&readmask);
        FD_SET (sock, &readmask);
        if (select (255, &readmask, NULL, NULL, &tv) > 0)
        {
            if (FD_ISSET (sock, &readmask))
            {
                int numb;
                numb = read (sock, buf, 100);

                // 12 bits
                if (ui->comboBox->currentIndex() == 1)
                {
                    if (numb == 14)
                    {
                        conta++;
                        //printf ("received %d bytes:\n", numb);
                        // print of counter
                        //printf ("%d,", buf[0]);
                        fprintf (data, "%d,", buf[0]);
                        for (i = 1; i < numb-1; i += 3)
                        {
                            v1 = buf[i] | ((buf[i + 1] & 0x0F) << 8);
                            v2 = buf[i + 2];
                            v2 = (v2 << 4) | ((buf[i + 1] & 0xf0) >> 4);
                            printf ("%d,%d,", v1, v2);
                            //fprintf (data, "%d,%d,", v1, v2);
                        }

                        printf ("\n");
                        //fprintf (data, "\n");
                    }
                }
            }
        }
    }
    fclose (data);
}

所以,当我点击调用此插槽的按钮时,它永远不会让我再次使用gui。

这适用于终端。

提前感谢。

2 个答案:

答案 0 :(得分:2)

您应该使用QSocketNotifier类而不是自己的select,并为Qt事件循环提供自己的文件句柄。

您还可以使用this overload of QFile::open将套接字转换为QIODevice实例。

第三种选择是将您自己的select循环放入不同的线程中,因此它不会阻止Qt主事件循环。但这会带来相当多的额外复杂性,所以我只是作为最后的手段来做到这一点。

答案 1 :(得分:1)

您在与GUI相同的线程中运行while循环,因此阻止了事件队列。你有两个选择:

  • 在循环过程中,请致电QCoreApplication::processEvents()。这会强制处理事件队列。
  • 将while循环逻辑分离到它自己的线程中。

第一个很多更简单,但通常被认为效率低下,因为几乎所有计算机都有多个核心。