1

カスタム QIODevice を実装しようとしています。

2 つの tcp ソケットを使用する検出器があります。1 つはコマンドの送信と応答の受信用で、もう 1 つはデータの読み取り専用です。

どうすればいいですか?クラスを作成し、QIODevice から派生させ、純粋な仮想メソッドを実装しようとしましたが、いくつかの問題に直面しました。

次のコードがあります。

class Detector : public QIODevice {
    Q_OBJECT
    Q_DISABLE_COPY(MasterDevice)

public:
    enum CHANNEL_TYPE {
        DataChannel,
        ControlChannel
    };

private:
    QTcpSocket *controlDevice;
    QTcpSocket *dataDevice;

    QHostAddress hostAddress;

    quint16 dataPort;
    quint16 controlPort;

public:
    explicit Detector(QObject *parent, QHostAddress hostAddress, quint16 dataPort, quint16 controlPort)
        : QIODevice(parent)
        , hostAddress(hostAddress)
        , dataPort(dataPort)
        , controlPort(controlPort)
    {
        controlDevice = new QTcpSocket(this);
        connect(controlDevice, SIGNAL(readyRead()),this, SLOT(controlChannelReadReady()));

        dataDevice = new QTcpSocket(this);
        connect(dataDevice, SIGNAL(readyRead()),this, SLOT(dataChannelReadReady()));
    }

    virtual ~Detector() {}

    bool open(OpenMode mode) override {
        QIODevice::open(mode);

        controlDevice->connectToHost(hostAddress, controlPort, QTcpSocket::ReadWrite);
        dataDevice->connectToHost(hostAddress, dataPort, QTcpSocket::ReadOnly);
    }

    qint64 readData(char *data, qint64 maxSize) override {
        QTcpSocket *socket;

        switch ( currentReadChannel() ) {
        case DataChannel:
            socket = dataDevice;
            break;
        case ControlChannel:
            socket = controlDevice;
            break;
        default:
            return -1;
            break;
        }

        return socket->read(data, maxSize);
    }

    qint64 writeData(const char * data, qint64 maxSize) override {
        QTcpSocket *socket;

        switch ( currentWriteChannel() ) {
        case DataChannel:
            socket = dataDevice;
            break;
        case ControlChannel:
            socket = controlDevice;
            break;
        default:
            return -1;
            break;
        }

        return socket->write(data, maxSize);
    }

private slots:
    void controlChannelReadReady() {
        emit channelReadyRead(ControlChannel);
    }

    void dataChannelReadReady() {
        emit channelReadyRead(DataChannel);
    }
};

基本的に私の質問は、これらのチャネルをどのように処理するかです。たとえば、qt documentationこれがあるからです

bool QIODevice::open(OpenMode mode)

デバイスを開き、その OpenMode を mode に設定します。成功した場合は true を返します。それ以外の場合は false を返します。この関数は、デバイスを開く open() またはその他の関数の再実装から呼び出す必要があります。

したがって、オーバーライドされたメソッドから呼び出す必要がありますOpen()が、このメソッドの実装を調べたところ、チャネル数が 1 に設定されていることがわかりました。この数を変更するにはどうすればよいですか?

QIODevice から継承しているバッファは何のためにありますか?どのように使用すればよいですか?

カスタム QIODevice を作成するポイントがありませんか? もしそうなら、私にそれを説明してください。

4

1 に答える 1

0

ここでサブクラス化する必要はほとんどありません。必要なQIODeviceセマンティックを使用してインターフェイスを設計および実装するだけです。

sendCommand();
responseReceived();
dataReady();
...
etc

QIODeviceファイル、ソケット、シリアルポートなどのさまざまなソースとの間でバイトストリームを読み書きするための共通インターフェースです。

于 2017-08-15T20:28:04.170 に答える