Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/129.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 信号槽弄得一团糟_C++_Qt_Logic - Fatal编程技术网

C++ 信号槽弄得一团糟

C++ 信号槽弄得一团糟,c++,qt,logic,C++,Qt,Logic,我正在尝试使用Qt创建一个图像保存应用程序。现在是存根 class ImageSaver:public QObject { int index; QWebPage * main_Page; QNetworkAccessManager * manager; QNetworkReply * reply; QString file_Name; QSet<QString> image_Addresses; QString web_Add

我正在尝试使用Qt创建一个图像保存应用程序。现在是存根

class ImageSaver:public QObject
{
    int index;
    QWebPage * main_Page;
    QNetworkAccessManager * manager;
    QNetworkReply * reply;
    QString file_Name;
    QSet<QString> image_Addresses;
    QString web_Address;
    Q_OBJECT
signals:
    void image_Saved();
public slots:
    void request_Image();
    void on_Finished(bool status);
    void got_Reply(QNetworkReply * reply);
public:
    ImageSaver();
    void start();
};

ImageSaver::ImageSaver()
{
    index = 0;

    manager = new QNetworkAccessManager;

    reply = NULL;

    connect(main_Page,SIGNAL(loadFinished(bool)),this,SLOT(on_Finished(bool)));

    connect(manager,SIGNAL(finished(QNetworkReply*)),this,SLOT(got_Reply(QNetworkReply*)));

    connect(this,SIGNAL(image_Saved()),this,SLOT(request_Image()));
}

void ImageSaver::start()
{
    //loads the url 
    // In the end of the loading it will emit load_Finished(bool)
    // So that signal will execute on_Finished(bool)
}

void ImageSaver::request_Image()
{
    QString temp_Address = *(image_Addresses.begin()+index);

   //makes a request to the server to give the image "temp_Address"
   //When the server gives the reply signal finished(QNetworkReply*) will be emitted
   // this in turn will call the got_Reply(QNetworkReply*)
}

void ImageSaver::on_Finished(bool status)
{
       //collects all the images's url addresses, and pushes them in the list 
        //"image_Addresses"
        //Then emits image_Saved();
        //This signal will wake up the function request_Image()
}

void ImageSaver::got_Reply(QNetworkReply * reply)
{
    //Image is extracted from the reply and got saved in the same name as in the page
    //index got increased;
    //emits the signal image_Saved();
    //This signal will activate the function request_Image()
}

int main(int argc,char * argv[])
{
    QApplication app(argc,argv);
    ImageSaver a;
    a.start();
    return app.exec();
}

#include "main.moc"

这个问题可能有很多解决方案。我想你应该看看。在简单的情况下,您可以使用布尔变量检查是否可以继续。您还应该考虑在忙于处理图像时要做什么。您可以将请求排队,也可以拒绝它们。此外,还可以实现线程化,以便新线程为新请求提供服务


p.S.信号对我来说更像事件而不是线程。

这个问题可能有很多解决方案。我想你应该看看。在简单的情况下,您可以使用布尔变量检查是否可以继续。您还应该考虑在忙于处理图像时要做什么。您可以将请求排队,也可以拒绝它们。此外,还可以实现线程化,以便新线程为新请求提供服务


p.S.信号对我来说更像是事件而不是线程。

错误是什么?为什么在末尾有一个
#include


仅供参考,您可以使用
QImage
类,该类包括从
QIODevice*
保存和加载,例如
QNetworkReply
。在庞大的Qt框架中重新发明轮子是极为罕见的。

错误是什么,为什么在最后有一个
#include


仅供参考,您可以使用
QImage
类,该类包括从
QIODevice*
保存和加载,例如
QNetworkReply
。在Qt这个庞大的框架中,很少需要重新设计轮子。

您的代码崩溃,因为您读取的内容超出了映像地址集的边界

void ImageSaver::request_Image()
{
    QString temp_Address = *(image_Addresses.begin()+index);
    ...

您在收到每个图像后增加索引,但代码中的任何地方都没有检查索引是否仍然小于image\u Addresses.size(),因此一旦取消引用image\u Addresses.begin()+index for index==image\u Addresses.size(),代码就会崩溃。

因为您读取的内容超出了image\u Addresses集的边界

void ImageSaver::request_Image()
{
    QString temp_Address = *(image_Addresses.begin()+index);
    ...

您在收到每个图像后增加索引,但代码中的任何地方都没有检查索引是否仍然小于image\u Addresses.size(),因此一旦取消引用image\u Addresses.begin()+index for index==image\u Addresses.size(),它将崩溃。

在哪里?有留言吗?您应该提供一个完整且最少的示例来演示该行为。插槽类似于函数调用,信号只是稍后(在事件循环期间)调用插槽的一种方式。不清楚为什么要将算法拆分为多个插槽。我会尝试将整个过程放在一个插槽中,看看您是否仍然崩溃。根据您当前的示例判断,您正在使用默认方法连接信号和插槽。这是一个直接连接,意味着您实际上只是在进行函数调用。这里没有多线程,除非你在我们看不到的地方做线程。Tom K引用了一个“排队连接”,但它看起来不像是您正在做的事情。请参见:如果它崩溃,请提供回溯。您对信号/插槽的假设是错误的,它们是正常的方法调用,不涉及多线程。@Tom请在编辑中尝试代码。如果你说如何把整个过程放在一个插槽中,我将非常感谢你。我认为你崩溃的原因如下。但是,使用msgbox调试这样的代码是危险的:如果有一个网络操作挂起,并且您打开了一个消息框,msgbox将在exec内部打开一个本地事件循环。如果网络op在对话框打开时返回,则被调用的插槽将更改应用程序的状态。一旦关闭对话框,exec()之后的代码将被执行,并且在exec()之前可能做出的任何假设都不再有效,因为网络op在这两者之间调用了插槽。最好不要在这样的上下文中使用阻塞exec()调用。它在哪里崩溃?有留言吗?您应该提供一个完整且最少的示例来演示该行为。插槽类似于函数调用,信号只是稍后(在事件循环期间)调用插槽的一种方式。不清楚为什么要将算法拆分为多个插槽。我会尝试将整个过程放在一个插槽中,看看您是否仍然崩溃。根据您当前的示例判断,您正在使用默认方法连接信号和插槽。这是一个直接连接,意味着您实际上只是在进行函数调用。这里没有多线程,除非你在我们看不到的地方做线程。Tom K引用了一个“排队连接”,但它看起来不像是您正在做的事情。请参见:如果它崩溃,请提供回溯。您对信号/插槽的假设是错误的,它们是正常的方法调用,不涉及多线程。@Tom请在编辑中尝试代码。如果你说如何把整个过程放在一个插槽中,我将非常感谢你。我认为你崩溃的原因如下。但是,使用msgbox调试这样的代码是危险的:如果有一个网络操作挂起,并且您打开了一个消息框,msgbox将在exec内部打开一个本地事件循环。如果网络op在对话框打开时返回,则被调用的插槽将更改应用程序的状态。一旦关闭对话框,exec()之后的代码将被执行,并且在exec()之前可能做出的任何假设都不再有效,因为网络op在这两者之间调用了插槽。最好不要在这样的上下文中使用blocking exec()调用。#include“main.moc”是在主cpp文件中有信号/插槽时的标准做法。它更多的是关于它在哪里而不是它在什么地方。@AJG85我想我使用了那个QImage类,查看编辑。我的意思是你可以做一些类似于
classimagesaver:publicqimage
的事情,然后在你的版本中使用包含你想要的额外位,并覆盖你想要的任何东西
void ImageSaver::request_Image()
{
    QString temp_Address = *(image_Addresses.begin()+index);
    ...