I use kid3-cli to quickly and easily read the tags via a QProcess. The communication runs via qProcess->write() and the readout via connection with readyReadStandardOutput. This ran smoothly until the new version 3.8.0. The new version no longer delivers data that can be read via readyReadStandardOutput. Maybe qProcess->write() doesn't work anymore, I can't say that due to lack of feedback from kid3-cli.
Is there any way to solve the problem?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
The thing which has changed is that kid3-cli now detects if its input is not a tty and then uses normal standard input instead of readline. I did this to make things easier, together with support for JSON input and output. I just made a small program and it seems to work, so maybe you need some changes in your code. You could use straceto see what is going on.
Thank you for the quick answer and the example. I tried it and it works, sorry that I didn't add an example code. The following sample program worked with the previous version, but there is no output with the new version. I'll have a closer look tomorrow.
constQStringKID3_BINARY="/usr/bin/kid3-cli";MainWindow::MainWindow(QWidget*parent):QMainWindow(parent),ui(newUi::MainWindow){ui->setupUi(this);c=newQProcess(this);connect(c,&QProcess::readyReadStandardOutput,[&]{qDebug()<<c->readAll();});c->start(KID3_BINARY);c->waitForStarted(1000);c->write("cd '/path/to/music folder'\n");c->write("select first\n");c->write("get all 12\n");}
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
If this is the whole application, using Qt seems to be an overkill, this could be done with a simple call kid3-cli -c "select first" -c "get all 12" "/path/to/music folder" or a series of calls in a shell script.
If you want to use Qt you should use an asynchronous event-based style with signals and slots and avoid blocking calls like waitForStarted. In your example, the three write calls are probably called in sequence without yielding the current thread and if the program is terminated afterwards, the readyReadStandardOutput will never be signalled.
If you use the standard command line interface, you should wait for the output after writing to the process standard input, otherwise it will be difficult to find out which output corresponds to which input. Using JSON you could use idfields to associate requests and responses, but also in this case it is probably better to handle responses before sending the next request.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Hi,
no this is not the whole application, but a newly started test project to debug the actual problem quickly and not have to deal with the whole application. Lambda connections are also used there. ;)
I haven't had time to check it out yet, but the problem is that this little test program works fine with kid3-cli 3.7.1 and you get the tags of the first file and absolutely nothing happens with kid3-cli 3.8.0.
Even if you just start the kid3-cli binary without any commands via QProcess->write(), i.e. only QProcess->start( "/usr/bin/kid3-cli" );, with the old version you get the response "kid3-cli> " via QProcess::readyReadStandardOutput, with the new version nothing happens.
So the described problem cannot be caused by QProcess->write(), because even a normal call of kid3-cli behaves quite differently than before.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
The prompt will only be written if isatty() returns 1, i.e. kid3-cli is connected to a real terminal. You could try the following to make it think that it is connected to a real terminal and thus get the old behavior: Instead of QProcess->start("/usr/bin/kid3-cli") run it with script using for example
Thanks a lot that works, but unfortunately my program still doesn't work properly with the new version of kid3-cli. There must be more changes under the hood that cause problems. As soon as I have more time, I'll take a closer look at it, so long I will still use the old version.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I use kid3-cli to quickly and easily read the tags via a QProcess. The communication runs via qProcess->write() and the readout via connection with readyReadStandardOutput. This ran smoothly until the new version 3.8.0. The new version no longer delivers data that can be read via readyReadStandardOutput. Maybe qProcess->write() doesn't work anymore, I can't say that due to lack of feedback from kid3-cli.
Is there any way to solve the problem?
The thing which has changed is that kid3-cli now detects if its input is not a tty and then uses normal standard input instead of readline. I did this to make things easier, together with support for JSON input and output. I just made a small program and it seems to work, so maybe you need some changes in your code. You could use
strace
to see what is going on.And the output I get is as expected
Thank you for the quick answer and the example. I tried it and it works, sorry that I didn't add an example code. The following sample program worked with the previous version, but there is no output with the new version. I'll have a closer look tomorrow.
If this is the whole application, using Qt seems to be an overkill, this could be done with a simple call
kid3-cli -c "select first" -c "get all 12" "/path/to/music folder"
or a series of calls in a shell script.If you want to use Qt you should use an asynchronous event-based style with signals and slots and avoid blocking calls like
waitForStarted
. In your example, the three write calls are probably called in sequence without yielding the current thread and if the program is terminated afterwards, thereadyReadStandardOutput
will never be signalled.If you use the standard command line interface, you should wait for the output after writing to the process standard input, otherwise it will be difficult to find out which output corresponds to which input. Using JSON you could use
id
fields to associate requests and responses, but also in this case it is probably better to handle responses before sending the next request.Hi,
no this is not the whole application, but a newly started test project to debug the actual problem quickly and not have to deal with the whole application. Lambda connections are also used there. ;)
I haven't had time to check it out yet, but the problem is that this little test program works fine with kid3-cli 3.7.1 and you get the tags of the first file and absolutely nothing happens with kid3-cli 3.8.0.
Even if you just start the kid3-cli binary without any commands via
QProcess->write()
, i.e. onlyQProcess->start( "/usr/bin/kid3-cli" );
, with the old version you get the response"kid3-cli> "
viaQProcess::readyReadStandardOutput
, with the new version nothing happens.So the described problem cannot be caused by
QProcess->write()
, because even a normal call of kid3-cli behaves quite differently than before.The prompt will only be written if
isatty()
returns 1, i.e.kid3-cli
is connected to a real terminal. You could try the following to make it think that it is connected to a real terminal and thus get the old behavior: Instead ofQProcess->start("/usr/bin/kid3-cli")
run it withscript
using for exampleThanks a lot that works, but unfortunately my program still doesn't work properly with the new version of kid3-cli. There must be more changes under the hood that cause problems. As soon as I have more time, I'll take a closer look at it, so long I will still use the old version.