0

这是我的 btconnect.h 文件

#ifndef BTCONNECT_H
#define BTCONNECT_H

#include "scandialog.h"

namespace Ui {
class BTConnect;
}

class BTConnect : public QWidget
{
    Q_OBJECT

public:
    explicit BTConnect(QWidget *parent = 0);
    ~BTConnect();

private slots:
    void on_ScanButton_clicked();

    void ScanBTDevices();

    //some slots here

    void ScanDialogShow();

    void ScanDialogClose();

public slots:
//some slots here

private:
    Ui::BTConnect *ui;

    QProcess BTscan_Process;

    scanDialog *scan;
};

#endif // BTCONNECT_H

btconnect.cpp

BTConnect::BTConnect(QWidget *parent) :
QWidget(parent),
ui(new Ui::BTConnect)
{
    //set the userinterface as BTConnect.ui
    ui->setupUi(this);

    scan = new scanDialog(this);
}


void BTConnect::ScanDialogShow()
{
    scan->show();
}

void BTConnect::ScanDialogClose()
{
    scan->close();
}

void BTConnect::ScanBTDevices()
{
    ScanDialogShow();

    //Command to scan nearby bluetooth devices
    //"hcitool scan"
    QString cmd("hcitool scan");

    //start the process
    BTscan_Process.start(cmd);

    //Wait for the processs to finish with a timeout of 20 seconds
    if(BTscan_Process.waitForFinished(20000))
    {
        //Clear the list widget
        this->ui->listWidget->clear();

        //Read the command line output and store it in QString out
        QString out(BTscan_Process.readAllStandardOutput());

        //Split the QString every new line and save theve in a QStringList
        QStringList OutSplit = out.split("\n");

        //Parse the QStringList in btCellsParser
        btCellsParser cp(OutSplit);

        for(unsigned int i = 0; i<cp.count(); i++)
        {
           //writing in listwidget
        }

    }

    ScanDialogClose();
}

void BTConnect::on_ScanButton_clicked()
{
    //Scan for available nearby bluetooth devices
    ScanBTDevices();
}

如果我使用上面的代码,qdialog scandialog 会在进程开始时打开并在 qlistwidget 中加载数据时关闭,但不会显示 qdialog scandialog 的内容。如果我将 show() 更改为 exec(),将显示内容,但 QProcess 在对话框关闭之前不会运行。

我希望对话框在 Qprocess 启动时打开,并在 qlistwidget 加载来自扫描的数据时关闭。我希望显示 scandialog 的内容。它有两个标签。一个带有 .GIF 文件,另一个带有文本说扫描。

任何帮助表示赞赏。

4

2 回答 2

1

当你这样做时你永远不会返回事件循环show(因为waitForFinished)并且你永远不会在你这样做时继续处理代码exec

而不是waitForFinished你应该连接到finished信号并在那里处理它并使用一个单次计时器来取消它:

void BTConnect::on_BTscanFinished()//new slot
{
   //Clear the list widget
    this->ui->listWidget->clear();

    //Read the command line output and store it in QString out
    QString out(BTscan_Process.readAllStandardOutput());

    //Split the QString every new line and save theve in a QStringList
    QStringList OutSplit = out.split("\n");

    //Parse the QStringList in btCellsParser
    btCellsParser cp(OutSplit);

    for(unsigned int i = 0; i<cp.count(); i++)
    {
       //writing in listwidget
    }
    ScanDialogClose();
}

void BTConnect::ScanBTDevices()
{
    ScanDialogShow();

    //Command to scan nearby bluetooth devices
    //"hcitool scan"
    QString cmd("hcitool scan");

    //start the process
    connect(BTscan_Process, SIGNAL(finished()), this, SLOT(on_BTscanFinished()));
    BTscan_Process.start(cmd);
    QTimer::singleShot(20000, scan, SLOT(close()));
}
于 2013-10-29T16:51:27.970 回答
1

问题是QDialog::execQProcess::waitForFinished函数阻塞事件循环。永远不要阻塞事件循环。所以你只需要更异步地做事情。

QProcess类可以使用类似的信号异步处理readReadStandardOutput。并且QDialog可以使用open插槽异步显示。

这个例子:

void ScanBTDevices() {
    // Open dialog when process is started
    connect(process, SIGNAL(started()), dialog, SLOT(open()));

    // Read standard output asynchronously
    connect(process, SIGNAL(readyReadStandardOutput()), SLOT(onReadyRead()));

    // Start process asynchronously (for example I use recursive ls)
    process->start("ls -R /");
}

void onReadyRead() {
    // Write to list widget
    dialog->appendText(QString(process->readAllStandardOutput()));
}

在按流程生成期间,数据将附加到对话框中。也使用QProcess::finished信号,您可以关闭对话框。

于 2013-10-29T16:54:54.410 回答