Cannot execute echo command in QProcess

后端 未结 2 1455
北恋
北恋 2020-12-21 18:46

I want to launch a SCPI command in my device using netcat utility under Ubuntu 10.04 LTS with Qt. My code looks like:

env = \"echo TRIG | nc 192.168.1.100 23         


        
相关标签:
2条回答
  • 2020-12-21 19:23

    You can't use the pipe command (|) with QProcess that way.

    There are a few ways to tackle this: -

    You can call the first command and retrieve its output before processing it either in Qt or with another call to QProcess.

    Or, create a script that you call from QProcess and retrieve the output.

    Finally, assuming you're using linux / OSX, you can call QProcess with /bin/bash and pass the command to that. For example: -

    env = "/bin/bash \"echo TRIG | nc 192.168.1.100 23 -q1\"";
    process1.execute(env);
    

    You can probably find an equivalent to /bin/bash for windows, perhaps cmd.exe

    0 讨论(0)
  • 2020-12-21 19:49

    The code below shows a fairly complete, asynchronous implementation of this functionality. It demonstrates how it can be done without launching external processes, and how to leverage C++11 lambdas in Qt 5. For Qt 4, the slots from main() would need to live in their own QObject-derived class.

    screenshot

    #include <QtWidgets>
    #include <QtNetwork>
    
    class SocketSignaler : public QObject
    {
       Q_OBJECT
       Q_SLOT void stateChanged(QAbstractSocket::SocketState state) {
          if (state == QAbstractSocket::UnconnectedState) emit unconnected();
          else emit busy();
          emit hasState(this->state());
       }
    public:
       explicit SocketSignaler(QAbstractSocket * socket) : QObject(socket) {
          connect(socket, &QAbstractSocket::stateChanged, this, &SocketSignaler::stateChanged);
          connect(&(const QObject&)QObject(), &QObject::destroyed, this, // defer signal emission
                  [=]{ emit stateChanged(socket->state()); }, Qt::QueuedConnection);
       }
       Q_SIGNAL void busy();
       Q_SIGNAL void unconnected();
       Q_SIGNAL void hasState(const QString &);
       QString state() const {
          switch (static_cast<QAbstractSocket*>(parent())->state()) {
          case QAbstractSocket::UnconnectedState: return "Disconnected";
          case QAbstractSocket::HostLookupState: return "Looking up host";
          case QAbstractSocket::ConnectingState: return "Connecting";
          case QAbstractSocket::ConnectedState: return "Connected";
          case QAbstractSocket::ClosingState: return "Closing";
          default: return {};
          }
       }
    };
    
    class Ui : public QWidget {
       Q_OBJECT
       Q_PROPERTY(bool busy WRITE setBusy)
       QVBoxLayout m_layout{this};
       QFormLayout m_form;
       QLineEdit m_target{"192.168.1.100"};
       QLineEdit m_message{"TRIG"};
       QLabel m_state;
       QDialogButtonBox m_box;
       QPushButton * const m_send = m_box.addButton("Send", QDialogButtonBox::AcceptRole);
       QPushButton * const m_cancel = m_box.addButton(QDialogButtonBox::Cancel);
       QMessageBox m_msgBox{this};
    public:
       Ui() {
          m_form.addRow("Target Host", &m_target);
          m_form.addRow("Command", &m_message);
          m_layout.addLayout(&m_form);
          m_layout.addWidget(&m_state);
          m_layout.addWidget(&m_box);
          m_msgBox.setIcon(QMessageBox::Critical);
          connect(m_send, &QPushButton::clicked, this, &Ui::send);
          connect(m_cancel, &QPushButton::clicked, this, &Ui::cancel);
       }
       void setState(const QString & text) { m_state.setText(text); }
       QString target() const { return m_target.text(); }
       QString message() const { return m_message.text(); }
       void showError(const QString & text) {
          m_msgBox.setText(text);
          m_msgBox.show();
       }
       void setBusy(bool busy) {
          m_send->setEnabled(!busy);
          m_cancel->setEnabled(busy);
       }
       Q_SIGNAL void send();
       Q_SIGNAL void cancel();
    };
    
    int main(int argc, char *argv[])
    {
       const int targetPort = 23;
       QApplication app{argc, argv};
       Ui ui;
       ui.show();
    
       QTcpSocket socket;
       SocketSignaler socketSig{&socket};
       QObject::connect(&socketSig, &SocketSignaler::hasState, &ui, &Ui::setState);
    
       QStateMachine machine;
       QState sReady{&machine};
       QState sBusy{&machine};
       sReady.assignProperty(&ui, "busy", false);
       sBusy.assignProperty(&ui, "busy", true);
       sReady.addTransition(&socketSig, &SocketSignaler::busy, &sBusy);
       sBusy.addTransition(&socketSig, &SocketSignaler::unconnected, &sReady);
    
       QObject::connect(&ui, &Ui::send, [&](){
          socket.connectToHost(ui.target(), targetPort);
       });
       QObject::connect(&ui, &Ui::cancel, [&](){ socket.abort(); });
       QObject::connect(&socket,
                        static_cast<void (QAbstractSocket::*)(QAbstractSocket::SocketError)>
                        (&QAbstractSocket::error), [&]()
       {
          ui.showError(socket.errorString());
       });
       QObject::connect(&socket, &QAbstractSocket::connected, [&](){
          auto msg = ui.message().toLatin1();
          msg.append('\n');
          if (socket.write(msg) >= msg.size()) socket.close();
       });
       QObject::connect(&socket, &QAbstractSocket::bytesWritten, [&](){
          if (!socket.bytesToWrite()) socket.close();
       });
    
       machine.setInitialState(&sReady);
       machine.start();
       return app.exec();
    }
    #include "main.moc"
    
    0 讨论(0)
提交回复
热议问题