Класс QProcess позволяет запускать и взаимодействовать с другими программами. Экземпляры класса работают асинхронно, выполняя всю работу в фоновом режиме, что не приводит к "замораживанию" пользовательского интерфейса. QProcess может известить приложение о завершении запущенной им программы или о наличии данных, полученных от нее, выдавая соответствующие сигналы.
В демонстрационных целях напишем небольшое приложение, которое предоставит пользователю интерфейс с внешней программой преобразования графических файлов. Для данного примера будет использоваться программа convert из пакета ImageMagick, которая доступна для большинства платформ.
Рисунок 10.1. Внешний вид приложения Image Converter.
QProcess *process;
QString fileFilters;
Утилита uic добавляет эти переменные в
класс ConvertDialog.
void ConvertDialog::init()
{
process = 0;
QStringList imageFormats = QImage::outputFormatList();
targetFormatComboBox->insertStringList(imageFormats);
fileFilters = tr("Images") + " (*." +
imageFormats.join(" *.").lower() + ")";
}
Переменная fileFilters содержит текст
описания и один, или более, шаблонов имен файлов (например, "Text
files (*.txt)"). Функция QImage::outputFormatList() возвращает список форматов
изображений, поддерживаемых Qt. Этот список тесно связан с опциями,
выбранными при установке библиотки.
void ConvertDialog::browse()
{
QString initialName = sourceFileEdit->text();
if (initialName.isEmpty())
initialName = QDir::homeDirPath();
QString fileName =
QFileDialog::getOpenFileName(initialName, fileFilters,
this);
fileName = QDir::convertSeparators(fileName);
if (!fileName.isEmpty()) {
sourceFileEdit->setText(fileName);
convertButton->setEnabled(true);
}
}
Кнопка Browse связана со слотом
browse(). Если ранее пользователь уже
выбирал файл, то путь поиска, для диалога выбора файла, назначается
исходя из полного имени предыдущего файла, в противном случае,
открывается домашний каталог.
void ConvertDialog::convert()
{
QString sourceFile = sourceFileEdit->text();
targetFile = QFileInfo(sourceFile).dirPath() + QDir::separator()
+ QFileInfo(sourceFile).baseName();
targetFile += ".";
targetFile += targetFormatComboBox->currentText().lower();
convertButton->setEnabled(false);
outputTextEdit->clear();
process = new QProcess(this);
process->addArgument("convert");
if (enhanceCheckBox->isChecked())
process->addArgument("-enhance");
if (monochromeCheckBox->isChecked())
process->addArgument("-monochrome");
process->addArgument(sourceFile);
process->addArgument(targetFile);
connect(process, SIGNAL(readyReadStderr()),
this, SLOT(updateOutputTextEdit()));
connect(process, SIGNAL(processExited()),
this, SLOT(processExited()));
process->start();
}
Кнопка Convert связана со слотом
convert(). По сигналу от кнопки собирается
имя целевого файла, из имени исходного файла и расширения,
соответствующего заданному формату.Затем создается экземпляр класса QProcess. После этого собирается список аргументов командной строки, с помощью функции addArgument(). Первым идет имя файла внешней программы. Далее следуют аргументы, которые будут ей передаваться.
После создания списка аргументов производится соединение сигнала readyReadStderr(), класса QProcess, со слотом updateOutputTextEdit() диалогового окна, чтобы выводить в QTextEdit сообщения от внешней программы, по мере их поступления. И затем соединяется сигнал processExited(), класса QProcess, со слотом processExited() диалогового окна.
void ConvertDialog::updateOutputTextEdit()
{
QByteArray data = process->readStderr();
QString text = outputTextEdit->text() + QString(data);
outputTextEdit->setText(text);
}
Как только внешняя программа выдаст что нибудь на stderr, будет вызван слот updateOutputTextEdit(). Сообщение будет прочитано и
записано в QTextEdit.
void ConvertDialog::processExited()
{
if (process->normalExit()) {
outputTextEdit->append(tr("File %1 created")
.arg(targetFile));
} else {
outputTextEdit->append(tr("Conversion failed"));
}
delete process;
process = 0;
convertButton->setEnabled(true);
}
По завершении внешнего процесса перед пользователем выводится
соответствующее сообщение, после чего процесс удаляется.Создание графического интерфейса, для консольных приложений, подобным образом, может оказаться очень полезным, потому что позволяет использовать функциональность, заложенную в уже существующие программы и нам не нужно ломать голову над собственной реализацией.
Пред. | В начало | След. |
Работа с файлами и каталогами. | На уровень выше | Контейнерные классы. |