在Qt中运行单独的进程或线程

时间:2009-05-28 22:11:00

标签: c++ multithreading qt concurrency

我正在写我的第一个适当有用的软件。其中一部分将涉及用户查看图像,并选择接受或拒绝它。执行此操作将导致图像保存到已接受或拒绝的文件夹,并可能旋转和/或调整大小。

目前,我的旋转/调整大小/保存操作暂停执行我的程序,但我希望它在后台运行,以便立即显示下一张图像。

在Qt中执行此操作的唯一方法是在单独的线程中处理图像,还是有另一种方法?我仍然对C ++和Qt感兴趣,所以我不想因为潜入新领域而迷惑自己!

5 个答案:

答案 0 :(得分:14)

Qt有线程支持。你可能会发现this example application很有趣,因为它与你描述的有些相似。

另外,here is the full Qt thread documentation

答案 1 :(得分:3)

这些任务非常适合线程。仍然,你应该首先执行一个“正常”的功能,当它工作时,添加一个读取队列并调用相同处理函数的线程。

Qt有很多工具可以帮助你解决这个问题,主要是大多数容器都是线程安全的,还有一些线程算法(比如map-reduce)。仍然,首先尝试同步。

答案 2 :(得分:2)

<强>被修改

对不起,伙计们,我很难将“排队自定义类型示例”链接到要求。

据我所知,一旦用户接受或拒绝了图像,它必须是可选的旋转和/或缩放,并始终保存到特定目录并继续下一个图像。 ( - &gt;不再与用户进行交互)
即使用户离开当前对话框,仍然需要保存图像。

“排队自定义类型示例”仅处理一个图像,始终链接到gui,当用户退出对话框时,线程操作将停止。
因此,如果他从Queued示例启动他的程序,他可能会开始编写一个受互斥锁保护的图像队列,这样如果有待处理的保存操作,他就可以将新图像添加到列表中。否则,用户仍然需要等待待处理的操作 第二个问题是,当对话框关闭时,他可能不想等待待处理的保存操作。

我要做的是满足要求是使用线程池。为线程池提供所需的保存操作,如果还需要旋转/缩放,则使用基于QRunnable的装饰器模式。所有排队都由库正确处理,即使用户离开当前对话框,也会执行待处理操作。 最后,我可能会使用Queued示例代码来加载新图像,并为用户提供加载操作的等待指示。

我的runnables和decorator可能看起来像这样......(可能还有一些额外的构造函数来替换set函数)所以我可以很容易地添加像QThreadPool::globalInstance()->start(saver );这样的新操作而不使用任何低级别同步对象。

class ImageDecorator : public QRunnable
{
    NextStep nextStep;
public:
    typedef boost::shared_ptr<QRunnable> NextStep;

    ImageDecorator(const NextStep& nextStep) : nextStep(nextStep) {
    }   

    ImageDecorator() : nextStep() {
    }

    // set/get image functions....

protected:
    void next() {
        if( nextStep )
            nextStep->run();
    }
};


class RotateImage : public ImageDecorator
{
public:
    typedef boost::shared_ptr<Image> Image;

    RotateImage(const NextStep& nextStep) : ImageDecorator( nextStep) {
    }   

    RotateImage() : ImageDecorator() {
    }
    // set angle functions....

private:
    void run()
    {
        // rotate the image
        // ...
        next();
    }
};

class ResizeImage : public ImageDecorator
{
public:
    typedef boost::shared_ptr<Image> Image;

    ResizeImage(const NextStep& nextStep) : ImageDecorator( nextStep) {
    }   

    ResizeImage() : ImageDecorator() {
    }
    // set size functions....

private:
    void run()
    {
        // resize the image
        next();
    }
};

class SaveImage : public ImageDecorator
{
public:
    typedef boost::shared_ptr<Image> Image;

    SaveImage(const NextStep& nextStep) : ImageDecorator(nextStep) {
    }   

    SaveImage() : ImageDecorator() {
    }
   // set fileName functions....

private:
    void run()
    {
        // save the image
        next();
    }
};

// save the image 
SaveImage *const saver( new SaveImage() );
saver->setImage( /*use shared pointer*/ );
saver->setFilename( ... );

QThreadPool::globalInstance()->start( saver );

// rotate and save the image 
const ImageDecorator::NextStep saver( new SaveImage() );
saver->setImage( /*use shared pointer*/ );
saver->setFilename( ... );
RotateImage *const rotateAndSave( new RotateImage( saver ) );
rotateAndSave->setImage( /*use shared pointer*/ );
rotateAndSave->setAngle( ... );

QThreadPool::globalInstance()->start( rotateAndSave );


// resize rotate  and  save the image 
const ImageDecorator::NextStep saver( new SaveImage() );
saver->setImage( /*use shared pointer*/ );
saver->setFilename( ... );
const ImageDecorator::NextStep rotateAndSave( new RotateImage( saver ) );
rotateAndSave->setImage(/*use shared pointer*/ );
rotateAndSave->setAngle( ... );
ResizeImage *const resizeRotateAndSave( new ResizeImage( rotateAndSave ) );
resizeRotateAndSave->setImage( /*use shared pointer*/ );
resizeRotateAndSave->setSize( ... );

QThreadPool::globalInstance()->start( resizeRotateAndSave );

答案 3 :(得分:1)

使用QThread创建单独的线程或使用QRunnable的线程池工作线程,或者查看高级QtConcurrent类。 Here是图像缩放的示例。

答案 4 :(得分:1)

最简单的方法是使用QtConcurrent :: run