Как я могу получить темные обнаруженные имена объектов, используя qt (QProcess)? - PullRequest
1 голос
/ 05 октября 2019

Я хочу вызвать команду darknet Detect для одного изображения из qt, используя класс QProcess. Это мой код главного окна:

MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    QProcess * process = new QProcess();
    QString temp = "./darknet detect cfg/yolov3.cfg yolov3.weights 
    iii.jpg";
    connect(process, SIGNAL(finished(int, QProcess::ExitStatus)), 
    this, SLOT(ReadOut(int, QProcess::ExitStatus)));
    process->start(temp);
}

void MainWindow::ReadOut(int i, QProcess::ExitStatus statur)
{
  QProcess *p = dynamic_cast<QProcess *>( sender() );
  if (p)
    ui->textBrowser->append( p->readAllStandardOutput() );  
  p->close();
  delete p;
}

Но так как после обнаружения darkent ждет другого входа, я не могу получить вывод терминала, потому что процесс все еще идет. Или может быть другая проблема.

Мой вопрос такой:

  1. Как я могу исправить свой код для получения имен обнаруженных объектов из процесса.

  2. Есть ли другой методреализовать это?

Ответы [ 2 ]

0 голосов
/ 06 октября 2019

Наиболее распространенные ошибки при использовании QProcess:

  • Относительный путь программы относительно рабочего каталога , который является исполняемой папкой, ночасто программа не находится в исполняемой папке.

  • Программа может использовать ресурсы, связанные с программой, поэтому в этих случаях рабочий каталог должен быть каталогом, в котором находится программа.

Учитывая вышеизложенное, решение имеет вид:

#include <QtWidgets>


class DarknetWidget: public QWidget{
    Q_OBJECT
public:
    DarknetWidget(QWidget *parent=nullptr): QWidget(parent)
    {
        QGridLayout *lay = new QGridLayout(this);

        lay->addWidget(new QLabel("Darket directory:"), 0, 0);
        directory_le = new QLineEdit;
        lay->addWidget(directory_le, 1, 0);
        QPushButton *directory_button = new QPushButton("Select");
        connect(directory_button, &QPushButton::clicked, this, &DarknetWidget::onSelectDirectory);
        lay->addWidget(directory_button, 1, 1);

        lay->addWidget(new QLabel("Command:"), 2, 0);
        command_le = new QLineEdit;
        command_le->setText("darknet detect cfg/yolov3.cfg");
        lay->addWidget(command_le, 3, 0, 1, 2);

        lay->addWidget(new QLabel("weights:"), 4, 0);
        weight_le = new QLineEdit;
        lay->addWidget(weight_le, 5, 0);
        QPushButton *weight_button = new QPushButton("Select");
        connect(weight_button, &QPushButton::clicked, this, &DarknetWidget::onSelectWeight);
        lay->addWidget(weight_button, 5, 1);


        lay->addWidget(new QLabel("Input image:"), 6, 0);
        image_le = new QLineEdit;
        lay->addWidget(image_le, 7, 0);
        QPushButton *image_button = new QPushButton("Select");
        connect(image_button, &QPushButton::clicked, this, &DarknetWidget::onSelectImage);
        lay->addWidget(image_button, 7, 1);

        run_btn = new QPushButton;
        run_btn->setText("Run");
        connect(run_btn, &QPushButton::clicked, this, &DarknetWidget::runDarket);
        lay->addWidget(run_btn, 8, 0, 1, 2);

        log_te = new QPlainTextEdit;
        log_te->setReadOnly(true);
        lay->addWidget(log_te, 9, 0, 1, 2);             

        resize(640, 480);

        process = new QProcess(this);
        process->setProcessChannelMode(QProcess::MergedChannels);
        connect(process, &QProcess::stateChanged, this, &DarknetWidget::onStateChanged);
        connect(process, &QProcess::readyReadStandardOutput, this, &DarknetWidget::onReadyReadStandardOutput);
    }
protected:
    void closeEvent(QCloseEvent *event){
        process->kill();
        QWidget::closeEvent(event);
    }
private Q_SLOTS:
    void onSelectDirectory(){
        QString filename = QFileDialog::getExistingDirectory(this, tr("Open Darket directory"));
        if(!filename.isEmpty()){
            directory_le->setText(filename);
        }
    }
    void onSelectWeight(){
        QString filename = QFileDialog::getOpenFileName(this, tr("Open weights path"));
        if(!filename.isEmpty()){
            weight_le->setText(filename);
        }
    }
    void onSelectImage(){
        QString filename = QFileDialog::getOpenFileName(this, 
            tr("Open image path"), 
            QDir::currentPath(),
            tr("Image Files (*.jpg)"));
        if(!filename.isEmpty()){
            image_le->setText(filename);
        }
    }

    void runDarket(){
        log_te->clear();
        process->setWorkingDirectory(directory_le->text());
        QString command = QString("%1 %2 %3")
            .arg(command_le->text())
            .arg(weight_le->text())
            .arg(image_le->text());
        process->start(command);
    }
    void onReadyReadStandardOutput(){
        log_te->insertPlainText(process->readAllStandardOutput());
        log_te->verticalScrollBar()->setValue(log_te->verticalScrollBar()->maximum());
    }
    void onStateChanged(QProcess::ProcessState state){
        if(state == QProcess::Running){
            run_btn->setEnabled(false);
        }
        else if(state == QProcess::NotRunning){
            run_btn->setEnabled(true);
        }
    }
private:
    QLineEdit *directory_le;
    QLineEdit *command_le;
    QLineEdit *weight_le;
    QLineEdit *image_le;
    QPushButton *run_btn;
    QPlainTextEdit *log_te;

    QProcess *process;
};

int main(int argc, char* argv[]) {
    QApplication app(argc, argv);
    DarknetWidget w;
    w.show();
    return app.exec();
}

#include "main.moc"

enter image description here

0 голосов
/ 05 октября 2019

То, что вы можете попытаться сделать, это использовать сигнал QProcess::readyReadStandardOutput() вместо сигнала завершения процесса.

...