Russian Qt Forum
Ноябрь 22, 2024, 06:38 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: 1 [2]   Вниз
  Печать  
Автор Тема: Не создается объект QPrinter в отдельном процессе.  (Прочитано 18894 раз)
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #15 : Июль 20, 2012, 10:58 »

Вот, что обнаружил: в консольном приложении для чтения данных stdin из родительского процесса реализован поток. Если его убрать - инициализации принтеров производится нормально.
Так это хорошо. А чем этот поток занят на момент зависания?
Записан
kosproger
Гость
« Ответ #16 : Июль 20, 2012, 13:56 »

Вот реализация потока:
datareader.h:
Код:
#ifndef DATAREADER_H
#define DATAREADER_H

#include <QThread>
#include <QTextStream>

class DataReader : public QThread
{
    Q_OBJECT
public:
    explicit DataReader(QObject *parent = 0);
    void run();
   
signals:
    void ftpExit();

    void ftpPrint();
   
public slots:
   
};

#endif // DATAREADER_H

datareader.cpp:
Код:
#include "datareader.h"

DataReader::DataReader(QObject *parent) :
    QThread(parent)
{
}

void DataReader::run() {
    QString data;
    QTextStream in(stdin);
    data = in.readLine();
    if (data.contains("stop")){
        this->ftpExit();
        fflush(stdin);
        this->quit();
    } else {
        if (data.contains("notprint")){
            this->ftpPrint();
            fflush(stdin);
        }
    }
    exec();
}

В main.cpp:
Код:
    FtpChecker *ftp = new FtpChecker(filePath,pdfPath,server,ftpUser,ftpPass,userName,fileTime,pdfTime,print);

    DataReader *reader = new DataReader();
    QObject::connect(reader,SIGNAL(finished()),&a,SLOT(quit()));
    QObject::connect(reader,SIGNAL(ftpExit()),ftp,SLOT(onFtpExit()));
    QObject::connect(reader,SIGNAL(ftpPrint()),ftp,SLOT(onFtpPrint()));
    reader->start();
    reader->moveToThread(reader->thread());

ftp - объект в котором производится непосредственно скачивание, печать и т.д.
Reader реализован для корректного выхода и отмены печати. Т.е. В зависимости от переданных параметров срабатыват сигналы ftpExit() или ftpPrint(), которые обрабатывает ftp.
На момент зависания поток пытается прочитать строку, т.е. Выполняется
Код:
data = in.readLine();

Пробовал не выделять отдельный поток, а в один запихнуть чтение stdin, работу с ftp и принтерами - то же самое.
Записан
Bepec
Гость
« Ответ #17 : Июль 20, 2012, 14:02 »

Сами себе и ответили. А уж обойти можно как угодно. К примеру читать по таймеру, а не readLine.

Ведь readLine ждёт знака конца строки для продолжения работы. А он вам скорее всего и не приходит.

Записан
kosproger
Гость
« Ответ #18 : Июль 20, 2012, 14:15 »

Bepec так ведь поток же отдельный, он не может блокировать главный цикл обработки событий, по идее...
Да и почему тогда отдельно запущенная консоль работает?
Записан
Bepec
Гость
« Ответ #19 : Июль 20, 2012, 14:18 »

Видимо у вас дальше по коду что-то, что требует сигнала от этого потока, ннэ?

К сожалению этого ж я не вижу и сказать ничего не могу.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #20 : Июль 20, 2012, 14:20 »

На момент зависания поток пытается прочитать строку, т.е. Выполняется
Код:
data = in.readLine();
Попробовать напр так

Код
C++ (Qt)
while (!in.canReadLine())
QThread::msleep(100);
data = in.readLine();
 
Записан
kosproger
Гость
« Ответ #21 : Июль 20, 2012, 14:25 »

Bepec, сигналы подключены к слотам объекта класса FtpChecker в main. Выше приведен код. Реализация слотов:
Код:
void FtpChecker::onFtpExit() {
    fflush(stdin);
    qDebug("Exiting.\r\n");
    ftp->abort(); //ftp здесь - объект QFtp
    ftp->close();
    timer->deleteLater();
    ftp->deleteLater();
}

void FtpChecker::onFtpPrint() {
    canPrint = false;
}
Записан
Bepec
Гость
« Ответ #22 : Июль 20, 2012, 14:30 »

Скажу проще - возможно, у вас не идёт дальше, ибо ждёт от ваших же классов каких-то таинственных действий. Возможно у драйверов принтера какая то заказяка. Возможно у вас в коде далее стоит Sleep(100500) и получается Ѡ.

Саму логику работы с принтером я не представляю пока, так что могу сказать только - Возможно...
Записан
kosproger
Гость
« Ответ #23 : Июль 20, 2012, 15:42 »

Igors, в QTextStream нет метода canReadLine(), попробовал сделать через QFile чтение, но тогда блокируется ввод. наткнулся на эту тему: http://www.prog.org.ru/topic_10611_0.html пытаюсь что-нибудь из нее выцепить.
Bepec, работу с принтером привожу ниже. После скачивания файла с фтп, если файл имеет расширение .pdf проверяю если имя принтера указано как default либо же недоступное имя, выбираю принтер по умолчанию, создаю объект принтера, указываю название принтера, параметры печати. Для преобразования страниц pdf файла к печати используется Poppler.
Код:
        case QFtp::Get: {
            flist.first()->close();
            QString curFile = flist.first()->fileName();
            curFile.replace(0,curFile.lastIndexOf("/") + 1,"");
            qDebug(QString("File " + curFile + " downloaded.\r\n").toUtf8());
            fflush(stdout);
            if (curFile.endsWith(".pdf",Qt::CaseInsensitive)) {
                if (canPrint) {
                    Poppler::Document *doc = Poppler::Document::load(filePath + "/" + curFile);
                    bool isOk = false;
                    if (!doc || doc->isLocked()) {
                        qDebug(QString("No access to file " + filePath + "/" + curFile + "\r\n").toUtf8());
                        fflush(stdout);
                    } else {
                        QPrinterInfo *printerInf = new QPrinterInfo();
                        QString printerName;
                        if (print == "default") {
                            printerName = printerInf->defaultPrinter().printerName();
                        } else {
                            bool flag = false;
                            for (int i = 0; i < printerInf->availablePrinters().count(); i++) {
                                if (printerInf->availablePrinters().at(i).printerName() == print) {
                                    printerName = print;
                                    flag = true;
                                    break;
                                }
                            }
                            if (!flag) {
                                printerName = printerInf->defaultPrinter().printerName();
                                qDebug(QString("Printer " + print + " was not found. Using default printer.\r\n").toUtf8());
                                fflush(stdout);
                            }
                        }
                        QPrinter *printer = new QPrinter(QPrinter::HighResolution);
                        printer->setPrinterName(printerName);
                        printer->setResolution(300);
                        int i = 0;
                        while (1) {
                            Poppler::Page* pdfPage = doc->page(i);
                            if (pdfPage == 0) {
                                break;
                            } else {
                                printer->setFullPage(true);
                                printer->setPaperSize(pdfPage->pageSizeF(),QPrinter::Point);
                                switch (pdfPage->orientation()) {
                                case Poppler::Page::Seascape:
                                    printer->setOrientation(QPrinter::Landscape);
                                    break;
                                case Poppler::Page::Landscape:
                                    printer->setOrientation(QPrinter::Landscape);
                                    break;
                                case Poppler::Page::Portrait:
                                    printer->setOrientation(QPrinter::Portrait);
                                    break;
                                case Poppler::Page::UpsideDown:
                                    printer->setOrientation(QPrinter::Portrait);
                                    break;
                                }
                                QImage image = pdfPage->renderToImage(300,300);
                                if (image.isNull()) {
                                    qDebug("Poppler error: can't create image.\r\n");
                                    fflush(stdout);
                                } else {
                                    QPainter painter;
                                    if (painter.begin(printer)) {
                                        painter.drawImage(0, 0, image);
                                        if (painter.end()) {
                                            isOk = true;
                                        } else {
                                            isOk = false;
                                            break;
                                        }
                                    }
                                }
                            }
                            delete pdfPage;
                            i++;
                        }
                    }
                    delete doc;
                    if (isOk) {
                        QDir dir(pdfPath);
                        if (!dir.exists())
                            dir.mkpath(pdfPath);
                        QFile file(filePath + "/" + curFile);
                        file.rename(pdfPath + "/" + curFile);
                        qDebug(QString(curFile + " printed\r\n").toUtf8());
                        fflush(stdout);
                    } else {
                        qDebug(QString(curFile + " NOT printed\r\n").toUtf8());
                        fflush(stdout);
                    }
                } else {
                    QFile file(filePath + "/" + curFile);
                    file.rename(pdfPath + "/" + curFile);
                }
            }
            ftp->remove(curFile);
            flist.removeFirst();
            break;
        }

С принтером больше ничего.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #24 : Июль 20, 2012, 16:47 »

Igors, в QTextStream нет метода canReadLine(),
А in.device()->canReadLine()? Или device() нулевое?
Записан
kosproger
Гость
« Ответ #25 : Июль 20, 2012, 16:52 »

Цикл работает, но то же самое, что и при QFile. Блокируется ввод. Т.е. Даже в консоли ничего не ввести... Злой
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #26 : Июль 20, 2012, 17:04 »

Ну хорошо, тогда может оставить in.readLine() но как-то дать ему вывод, чтобы он прочитал и больше на этой строке не стоял пока печать идет. На (самый) худой конец замочить читающий поток (terminate).
Записан
kosproger
Гость
« Ответ #27 : Июль 20, 2012, 17:10 »

Примерно так и пробую сейчас сделать, а именно: из GUI отправляю пустую строку ("\r\n") приложению.
Записан
kosproger
Гость
« Ответ #28 : Июль 20, 2012, 17:21 »

Да, получилось наконец-то!!!  Улыбающийся
Передалал так:
Код:
void DataReader::run() {
    QString data;
    QTextStream in(stdin);
    while (1) {
        data = in.readLine();
        this->msleep(100);
        if (data.contains("stop")){
            this->ftpExit();
            fflush(stdin);
            this->quit();
            break;
        } else {
            if (data.contains("notprint")){
                this->ftpPrint();
                fflush(stdin);
            }
        }
    }
}

В GUI по таймеру каждые 100 мсек отправляется пустая строка.
Так и оставлю, а то замучал этот проект совсем. Хотя все же интересно, что за такая беда все-таки с принтерами...

Всем спасибо большое!! Улыбающийся
Записан
Bepec
Гость
« Ответ #29 : Июль 20, 2012, 21:19 »

Причина то выяснена - у вас что-то в программе не так Улыбающийся
Позже когда-нибудь посмотрите и скажите - как же я тогда сразу не догадался Улыбающийся
Записан
Страниц: 1 [2]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.074 секунд. Запросов: 22.