I tried to use my custom sequential QIODevice as I would use a file. All data was read from the device after QNAM::post was called, but then sending hanged. Without calling post, reading didn't start at all.

This looks like catch 22: post() expects finished() to be emitted, but no data is read before post() is called...

What is the proper way to use sequential QIODevice with QHttpMultipart?

As far as I can see the QHttpMultiPart and QNetworkReply... try to read until the device returns -1 when calling read(...)
Make sure that your implementation of readData(...) returns -1 when it gets called after all data was already read!

... as QHttpMultiPart doesn't listen to any signales, the signals of your device don't care, it's all about the return-code of read/readData

I first was a bit puzzled how situation is exactly ... so I setup a small project to reproduce it and I also get to the point that it reads (on my case it even reads with -1 twice) ...

As I was now confused what all the "isSequential" special handling should do, I changed it to return false (even so my device acts like sequential) ... and then it worked, it generated the data and send it to my webserver ... not sure what the side-effect of this is

Btw. I think the code which queries isSequential() interprets it as "device doesn't know his size" ... and the QNAM code that follows on isSequential==true buffers all data from the device (probably to calculate a valid content-length) ...

I haven't saw any code that use the other aspects of "isSequential" (like seek() or pos()) ... so if you could calculate the size and don't want the data to be buffered, isSequential==false and a valid size seems to be the right way

... but that still doesn't explain why QHttpMultiPart with isSequential doesn't work ... looking into unit-tests ... btw. THERE IS NO UNIT TEST for isSequential-Devices in the unit-tests for QHttpPart, so if this code is broken it wouldn't be detected anyway ...