2017-03-02 22 views
0

ユーザーが特定のデータファイルをアップロードしてプッシュボタンを押すと、一連のプロットが生成されます。プッシュボタンが押されると、プログラムは一連の計算を計算し、いくつかのグラフをプロットして、関数呼び出しQDialog::exec()の画面に表示します。私が達成しようとしているのはを使って生成されたプロットのスクリーンショットをgrabにすることです。したがって、本質的にQWidget::grab()QDialog::exec()の直後に呼び出されます。しかし、特定のウィンドウがユーザによって閉じられるまでQDialog::exec()が動作し続けるので、ウィンドウを閉じた後にQWidget::grab()を呼び出しても、望ましい結果が得られません。QThreadsを使用してQDialog :: exec()を実行中にQWidget :: grab()を実行する

これは私のコードの一部です。 graphWindow.savePlots()

void GraphWindow::savePlots() 
{ 

    QStringList plotNames; 
    plotNames << "Income Statement (Plot A)" << "Income Statement (Plot B)" << "Balance Sheet (Plot A)" 
      << "Balance Sheet (Plot B)" << "Cash Flow Plot" << "Holistic Stock Performance"; 

    for(int item = 0; item < ui->graphTab->count(); item++) 
    { 
     ui->graphTab->setCurrentIndex(item); 
     QWidget * currentWidget = ui->graphTab->widget(item); 

     int height = currentWidget->height(); 
     int width = currentWidget->width(); 
     int x = currentWidget->x(); 
     int y = currentWidget->y(); 

     QRect grabRect(x,y,width,height); 

     //destImagePath is a global variable 
     QString imageFilePath = destImagePath; 
     imageFilePath.append(plotNames.at(item)); 
     imageFilePath.append(".png"); 

     currentWidget->grab(grabRect).save(imageFilePath); 
    } 

    //Reset to first tab after grab 
    ui->graphTab->setCurrentIndex(0); 
} 

Iウィンドウがまだその画面のグラブは、所望の結果を生み出すように動作している間GraphWindow::savePlots()を実行する別のQThreadを実行してQDialog::exec()をバイパスすることを考えたでmainwindow.cpp

graphWindow.setWindowState(Qt::WindowMaximized); 
    graphWindow.exec(); 
    graphWindow.savePlots(); 

これを行うにはもっと良い方法はありますか?私は1つの関数を呼び出すだけで新しいQThreadを作成することは非常に非効率的だと思います。たとえそうでないとしても、これが同時にQThreadsに実装される方法を説明してください。あなたのケースでは

+0

ワーカースレッドからウィジェットメソッドを呼び出すのは間違っています。GUIがUIスレッド上で動作するように設計されていれば、機能しないかもしれません。ダイアログを実行した状態で 'savePlots()'を呼び出すだけでよいのです。ダイアログが終了する前にそれをしてください。 – AlexanderVX

+0

それはコンストラクタで呼び出すことですか? (オブジェクトが最初に作成されたときに取得するものがないので、動作しないことはわかっています)ダイアログから 'saveplots()'を呼び出すにはどうすればよいですか?私はあなたが何を意味しているのか知っていますが、それを実装する方法には自信がありません。あなたがplsを精巧にすることができれば本当に役に立ちますか? – Vino

+0

なぜコンストラクタからですか?写真はいつ準備ができていると思われますか?あなたが知っておくべき。私たちはそれを見ることはできません。 – AlexanderVX

答えて

2

、QThreadを使用して、またはQtConcurrentを使用して::実行が実際には必要ないが、あなたの代わりにあなたのケースで

QTimer::singleShot(0, &graphWindow, &GraphWindow::savePlots); 
graphWindow.exec(); 

優位を使用して、メインスレッド上のスロットにコールをキューイングすることができ、それメインスレッド上で実行されるので、キャプチャのスレッド、同期などについて気にする必要はありません(Qtを使用しても簡単です)。

このアプローチの唯一の制限は、キャプチャ期間中アプリケーションを効果的に「フリーズ」することです。これは通常1秒よりもかなり短くなることを考慮すると、かなり許容できるはずです。

+0

魅力的な作品です。どうもありがとうございます。私はあなたのコードに小さな調整を加えました(EDITで追加されました)。 – Vino

+0

編集に感謝、私の悪い;)。どういたしまして ! –

関連する問題