2014-02-20 2 views
0

모든 직렬 포트를 찾고 열기, 쓰기 및 닫기를하고 QML에서이 메서드를 호출하기 위해 Q_INVOKABLE에 사용하는 C++ 메서드를 작성했습니다. QML에서, 먼저 LoadingPage.qml을 StackView에 넣은 다음 onClicked : Button 슬롯 안에 find() 직렬 포트를 호출합니다.QtQuick 애니메이션이 목록에서 열리고 직렬 포트가 열림

문제점 : 많은 직렬 포트가 연결되어있는 경우 LoadingPage.qml을 고정하면 동결됩니다. 함수 찾기가 애니메이션 시작을 다시 끝내면 애니메이션이 시작된 다음 즉시 멈 춥니 다. [SerialPort.qml] 어떻게 해결할 수 있을까요?

//SerialPort.qml 
Button { 
    text: qsTr("start") 
    onClicked: { 
     stackView.push(Qt.resolvedUrl("LoadingPage.qml")) 
     module.find() 
    } 
} 


QVector<QString> Physical::find() 
{ 
    m_ports.clear(); 

    foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts()) { 
     bool hasError = false; 

     QSerialPort port; 
     port.setPort(info); 

     if (port.open(QIODevice::ReadWrite)) { 
      if (!hasError && !port.setBaudRate(serial::baudRate)) { 
       emit error(tr("Can't set baud to %1, error %2") 
          .arg(port.portName()) 
          .arg(port.error())); 
       hasError |= true; 
      } 
      if (!hasError && !port.setDataBits(serial::dataBits)) { 
       emit error(tr("Can't set data bits to %1, error %2") 
          .arg(port.portName()) 
          .arg(port.error())); 
       hasError |= true; 
      } 

      if (!hasError && !port.setParity(serial::parity)) { 
       emit error(tr("Can't set parity to %1, error %2") 
          .arg(port.portName()) 
          .arg(port.error())); 
       hasError |= true; 
      } 
      if (!hasError && !port.setStopBits(serial::stopBits)) { 
       emit error(tr("Can't set stop bits to %1, error %2") 
          .arg(port.portName()) 
          .arg(port.error())); 
       hasError |= true; 
      } 
      if (!hasError && !port.setFlowControl(serial::flowCtrl)) { 
       emit error(tr("Can't set flow control to %1, error %2") 
          .arg(port.portName()) 
          .arg(port.error())); 
       hasError |= true; 
      } 
      if (!hasError) { 
       m_ports.append(port.portName()); 
      } 

      QByteArray data; 
      data.resize(1); 
      data[0] = ID_READ; 

      port.write(data); 
      port.close(); 
     } 
    } 

    return m_ports; 
} 
+0

각 포트가 요청한 매개 변수를 지원하는 경우 테스트 이유를 이해; 하지만 왜 각 포트에 데이터를 보내고 아무것도하지 않았는지 이해하지 못합니다 (내부 목록에 이미 포트를 저장했습니다 ...). 문제를 테스트하여 일부 유형의 장치를 검색 하시겠습니까? – leemes

답변

4

코드는 GUI 스레드에서 실행되며 GUI 스레드를 차단하므로 사용자 상호 작용도 중지됩니다.

별도의 스레드에서 검사를 수행해야합니다. Qt Concurrent 프레임 워크는 모든 스레드에서 수행 할 수있는 자체 포함 된 작업을 수행하기 때문에 완벽합니다. find() 메서드는 독립 실행 형 함수 또는 정적 메서드로 바뀔 수 있습니다 (실제로는 그 것이기 때문에). 람다에서 this을 캡처 할 수도 있습니다. 다음과 같이

그런 다음 그것을 실행할 것 :

class Physical { 
    QFuture<QStringList> m_future; 
    QFutureWatcher<QStringList> m_futureWatcher; 
    // A string list is a simpler type to type :) 
    static QStringList doFindPorts() { 
    ... 
    } 
    Q_SLOT void findPortsFinished() { 
    QStringList ports(m_future); 
    // use the list of ports 
    } 

public: 
    Physical() { 
    connect(&m_futureWatcher, SIGNAL(finished()), SLOT(findPortsFinished())); 
    m_futureWatcher.set(m_future); 
    ... 
    } 
    Q_SLOT void findPorts() { 
    if (m_future.isRunning()) return; 
    m_future = QtConcurrent::run(doFindPorts); 
    } 
};