我在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。
这适用于终端。
提前感谢。
答案 0 :(得分:2)
您应该使用QSocketNotifier类而不是自己的select
,并为Qt事件循环提供自己的文件句柄。
您还可以使用this overload of QFile::open将套接字转换为QIODevice实例。
第三种选择是将您自己的select
循环放入不同的线程中,因此它不会阻止Qt主事件循环。但这会带来相当多的额外复杂性,所以我只是作为最后的手段来做到这一点。
答案 1 :(得分:1)
您在与GUI相同的线程中运行while
循环,因此阻止了事件队列。你有两个选择:
QCoreApplication::processEvents()
。这会强制处理事件队列。第一个很多更简单,但通常被认为效率低下,因为几乎所有计算机都有多个核心。