打开QDialog并同时运行QProcess

时间:2013-10-29 14:46:42

标签: qt signals-slots qprocess qdialog

这是我的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文件,另一个用文字说扫描。

感谢任何帮助。

2 个答案:

答案 0 :(得分: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()));
}

答案 1 :(得分: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信号,您可以关闭对话框。