桌面界面的 Qt 线程



我正在为3D打印机开发Qt界面。当我点击打印按钮(打印机开始打印)时,界面崩溃。我正在使用以下代码:

*future= QtConcurrent::run(Imprimir,filename.toUtf8().data());

我可以用什么来解决它??我可以使用哪些类型的线程????

我需要在打印机打印时使用界面(可能需要几分钟)。

谢谢你的提前。

编辑:

Imprimir功能:

int Imprimir(char *fich)
{
    char *aux = new char;
    FILE *f;
    f=fopen(fich, "r");
     while(!feof(f)){
        fgets(aux, 200, f);
        Enviar(aux);
        while(!seguir_imprimiendo);
     }
     Sleep(7000);
    return 0;
}

不使用QFile使生活变得比必要的更难。当你使用QFile时,你不必处理愚蠢的事情,比如传递C字符串文件名。您可能会做错,因为谁能保证平台希望它们以UTF-8编码。Qt的全部意义在于它可以帮助您避免此类问题。它们得到照顾,代码在多个平台上进行测试,以确保每种情况下的行为都是正确的。

如果不使用 QByteArrayQFile ,您很可能会犯一些愚蠢的错误,例如分配单个字符缓冲区然后假装它有 200 个字符长的 C 经典错误。

我认为没有理由用这种方法睡觉。等待继续标志seguir_imprimiendo更改也是没有意义的,因为Enviar在同一线程中运行。它应该阻止,直到发送数据。

我假设你也已经通过QtConcurrent::run运行了Enviar代码。这是不必要的,并导致死锁。想一想,如果空闲线程在运行时永远不可用Imprimir会发生什么。对于运行Imprimir池限制为仅一个线程是有效的。你不能简单地假装它不会发生。

bool Imprimir(const QString & fileName)
{
  QFile src(fileName);
  if (! src.open(QIODevice::ReadOnly)) return false;
  QByteArray chunk;
  do {
    chunk.resize(4096);
    qint64 read = src.read(chunk.data(), chunk.size());
    if (read < 0) return false;
    if (read == 0) break; //we're done
    chunk.resize(read);
    if (!Enviar(chunk)) return false;
  } while (! src.atEnd());
  return true;
}
bool Enviar(const QByteArray & data)
{
  ...
  return true; // if successful
}

假设Imprimir没有问题,问题可能出在filename.toUtf8().data()上。从此函数获取的数据指针仅在filename范围内有效。当filename超出范围时,数据可能会被删除,并且访问数据的任何代码都将崩溃。

为了安全起见,应更改Imprimir函数以接受QString参数,而不是char*

如果您无法更改Imprimir函数(例如,因为它在另一个库中),则必须将其包装在您自己的接受 QString 的函数中。如果您使用的是 C++11,则可以使用 lambda 表达式来完成这项工作:

QtConcurrent::run([](QString filename) {
    Imprimir(filename.toUtf8().data());
}, filename);

如果没有,则必须编写一个单独的ImprimirWrapper(QString filename)函数并使用QtConcurrent::run调用它。

最新更新