2013-02-11 132 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