The OpenNET Project
 
Поиск (ключи):  ПРОГРАММЫ СТАТЬИ СОВЕТЫ ФОРУМ
ССЫЛКИ НОВОСТИ (+) MAN'ы ДОКУМЕНТАЦИЯ

Каталог документации / Раздел "Программирование, языки" / Оглавление документа

10.4. Взаимодействия между процессами.

Класс QProcess позволяет запускать и взаимодействовать с другими программами. Экземпляры класса работают асинхронно, выполняя всю работу в фоновом режиме, что не приводит к "замораживанию" пользовательского интерфейса. QProcess может известить приложение о завершении запущенной им программы или о наличии данных, полученных от нее, выдавая соответствующие сигналы.

В демонстрационных целях напишем небольшое приложение, которое предоставит пользователю интерфейс с внешней программой преобразования графических файлов. Для данного примера будет использоваться программа convert из пакета ImageMagick, которая доступна для большинства платформ.

Рисунок 10.1. Внешний вид приложения Image Converter.


Форма приложения была разработана в среде визуального построителя интерфейсов Qt Designer. Соответствующий .ui находится на CD, сопровождающем книгу. Здесь же мы сконцентрируем все свое внимание на содержимом файла .ui.h, который содержит исходный код. Обратите внимание: переменные process и fileFilters были объявлены в Qt Designer, на вкладке Members следующим образом:
    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); 
}
      
По завершении внешнего процесса перед пользователем выводится соответствующее сообщение, после чего процесс удаляется.

Создание графического интерфейса, для консольных приложений, подобным образом, может оказаться очень полезным, потому что позволяет использовать функциональность, заложенную в уже существующие программы и нам не нужно ломать голову над собственной реализацией.


Подпишись на Linux Format и получи один из 3 ценных призов!

Началась подписка на журнал Linux Format на 2010 год. Спешите оформить подписку на единственный в России ежемесячный журнал о Linux!

Все, оформившие подписку на печатную версию журнала, получают диск с архивом журнала Linux Format за 2005-2009г. в подарок. Также в подарок вы получаете именную электронную версию в формате PDF. Теперь вы можете приступить к чтению журнала сразу в момент выхода свежего номера, не дожидаясь, пока вам доставят бумажную версию.

Кроме того, все, оформившие подписку на первую половину или весь 2010 год в интернет-магазине ГНУ/Линуксцентра, автоматически становятся участниками розыгрыша ценных призов:


  Закладки на сайте
  Проследить за страницей
Created 1996-2010 by Maxim Chirkov  
ДобавитьРекламаВебмастеруГИД  
RUNNet TopList