2017-03-02 2 views
0

J'ai écrit un programme Qt dans lequel une série de graphiques est générée lorsque l'utilisateur télécharge un certain fichier de données et touche un bouton-poussoir. Lorsque le bouton-poussoir est enfoncé, le programme calcule une série de calculs et trace une poignée de graphiques et les affiche sur l'écran de l'appel de fonction QDialog::exec(). Ce que j'essaie de réaliser est de grab les captures d'écran des parcelles générées en utilisant QWidget::grab(). Donc, essentiellement le QWidget::grab() est appelé juste après QDialog::exec(). Mais puisque QDialog::exec() continue à fonctionner jusqu'à ce que la fenêtre particulière soit fermée par l'utilisateur, l'appel QWidget::grab() après la fermeture de la fenêtre ne donne pas les résultats souhaités.Utilisation de QThreads pour exécuter QWidget :: grab() pendant QDialog :: exec()

Cela fait partie de mon code;

Dans mainwindow.cpp

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

Dans 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); 
} 

Je pensais sans passer QDialog::exec() en exécutant une autre QThread qui exécute la GraphWindow::savePlots() alors que la fenêtre est toujours en cours d'exécution afin que les captures d'écran produisent des résultats souhaités.

Y a-t-il une meilleure façon de faire cela? Je pense que la création d'un nouveau QThread juste pour appeler une fonction est très inefficace. Même si ce n'est pas, pourriez-vous s'il vous plaît expliquer comment cela pourrait être mis en œuvre dans QThreads concurrent.

+0

Il est erroné d'appeler des méthodes de widget à partir du thread de travail: peut ou ne peut pas fonctionner tant que GUI conçu pour se comporter sur le thread UI. Vous devriez simplement appeler 'savePlots()' depuis la boîte de dialogue exécutée. Faites-le juste avant que la boîte de dialogue ne se ferme. – AlexanderVX

+0

cela signifie-t-il l'appeler dans le constructeur? (Je sais que cela ne fonctionnera pas car il n'y a rien à saisir quand l'objet est créé) Comment appeler le 'saveplots()' de la boîte de dialogue? Je sais ce que vous voulez dire mais pas si confiant dans la façon de l'implémenter. Ce serait vraiment utile si vous pouvez élaborer des pls? – Vino

+0

Pourquoi du constructeur? Quand l'image est censée être prête? Tu devrais savoir. Nous ne pouvons pas voir ça. – AlexanderVX

Répondre

2

Dans votre cas, en utilisant un QThread ou en utilisant QtConcurrent :: run est en fait pas nécessaire, vous pouvez plutôt la file d'attente d'un appel à une fente sur le thread principal en utilisant

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

L'avantage dans votre cas, il qu'il fonctionne sur le thread principal, donc vous n'avez pas à vous soucier des threads, de la synchronisation, et tout le reste pour la capture (même si Qt le rend plus facile). La seule limitation de cette approche est qu'elle gèrera efficacement votre application pendant la durée de la capture. Cela devrait normalement être tout à fait acceptable, étant donné qu'il serait significativement moins d'une seconde.

+0

Fonctionne comme un charme. Merci beaucoup. J'ai fait un petit ajustement à votre code (ajouté dans l'EDIT). – Vino

+0

Merci pour le montage, mon mauvais;). De rien ! –