2013-02-11 141 views
0

我已经写了一个程序在C中通过蓝牙连接PC与设备。程序从终端运行,收到的数据也显示在终端中。到现在为止还挺好。在linux中使用蓝牙与qt

现在我已经创建在QT的GUI,在其主要目的是提供其在终端中所示之前,现在在qwtplots的信息。

那么,我可以到目前为止设备与PC与GUI连接,但是当我请求信息形成装置,它在所述终端中示出,但是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。

这在终端工作。

在此先感谢。

+0

无论你的代码正在等待一个阻塞调用返回,或者你的'conta'变量没有被递增(不足为奇考虑很多条件语句如何要彻底得到)。你的'printf'说什么? – cmannett85 2013-02-11 15:31:48

+0

它正在打印值,但是当'conta'达到99时程序崩溃。直到那时它冻结。 – SamuelNLP 2013-02-11 15:37:29

回答

2

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

您还可以使用this overload of QFile::open把你的插座变成了QIODevice实例。

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

1

您正在运行在同一个线程中GUI的while循环,使事件队列被阻塞。您有两种选择:

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

第一个是简单,但通常被认为是低效的,因为刚才的所有有关的所有计算机具有多个核心。

+0

如果它是一个普通的GUI应用程序,那么'select'的'processEvents'超时必须非常短,产生不必要的系统负载,所以我不会使用它。它基本上是睡眠和GUI轮询循环... – hyde 2013-02-11 18:22:56