2017-01-24 8 views
1

私はQtのコンテキストでIrrlichtを使用しています。これを行うには、QWidgetにIrrlichtデバイスを表示するIrrlichtWidgetクラスがあります。ここでは、そのクラスの関連する部分である:私はQMessageBoxを使用するまでQMessageBoxを開くときにIrrlichtウィンドウが黒くなるのはなぜですか?

class IrrlichtWidget : public QWidget{ 
Q_OBJECT 
public: 
    IrrlichtWidget(){ 
     irr::SIrrlichtCreationParameters params; 
     params.DriverType = irr::video::EDT_OPENGL; 
     params.WindowId = (void*)winId(); 
     m_device = irr::createDeviceEx(params); 

     setAttribute(Qt::WA_OpaquePaintEvent); 

     m_timer = new QTimer; 
     m_timer->setInterval(0); 
     QObject::connect(m_timer, &QTimer::timeout, [this](){ 
      m_device->getVideoDriver()->beginScene(true, true, irr::video::SColor(255, 255, 255, 255)); 
      m_device->getSceneManager()->drawAll(); 
      m_device->getVideoDriver()->endScene(); 
      m_device->run(); 
     }); 
     m_timer->start(); 
    } 
private: 
    irr::IrrlichtDevice *m_device; 
    QTimer *m_timer; 
} 

これだけで正常に動作します。このクラスでプログラミングしていて、QMessageBoxを使用したかったときに、メッセージボックスを開くたびにIrrlichtウィジェットが黒くなっていたことに気付きました。私はこれをしなかった場合は、背景が黒だった

QObject::connect(m_timer, &QTimer::timeout, [this](){ 
    m_device->getVideoDriver()->beginScene(true, true, irr::video::SColor(255, 255, 255, 255)); 
    m_device->getSceneManager()->drawAll(); 
    m_device->getVideoDriver()->endScene(); 
    m_device->run(); 
    QMessageBox::information(this, "Foo", "Bar"); 
}); 

black background with message box

それはこのように見えたように、何が起こっていたかを見つけるためにしようとするために、私はIrrlichtをメインループに QMessageBoxを挿入しましたここでは、比較するため

は、それはそれでQMessageBoxを持っていないことを唯一の違いと全く同じプログラムです:

what i want

Irrlichtのメインループのどこにでも、最初、最後、最後に、同じことをやってみました。 QMessageBoxQFileDialogなど

私もコンストラクタで​​行を削除しようとした、その後、背景がベージュの代わりに黒だった:それは、Qtのダイアログボックスのすべての種類のためにこれを行います。同じ色ではありませんが、同じ問題です。

QMessageBoxは、Irrlichtウィジェットの内容を何とか消去しているようです。なぜこれをやっているのですか?どうすれば修正できますか?

答えて

0

QMessageBoxの静的関数(QMessageBox::informationなど)がメインループをブロックしているため、Irrlichtウィジェットが黒くなってしまうという問題があります。これを回避する方法は、QMessageBoxオブジェクトを作成し、open()メソッドを使用してオブジェクトを開くことです。静的関数によって使用されるexec()メソッドは、メインループをブロックし、Irrlichtウィジェットを黒にしますが、open()メソッドはメインループをブロックしないため動作します。

open()を使用して関数を作成しました。これはQMessageBox::informationと同じことをしますが、Irrlichtで動作します。 open()メソッドはメインループをブロックしないため、作成した関数はlambdasとfinishedシグナルを使用して、メッセージボックスが閉じた後の処理を処理します。ここでの機能はそれを使用する方法の例と一緒にいる:彼は新しいダイアログボックスを開きたい場合

#include <QMessageBox> 
#include <functional> 

void showMessageBox(std::function<void(QMessageBox::StandardButton)> lambda, QWidget *parent, const QString &title, const QString &text, QMessageBox::Icon icon = QMessageBox::Information, QFlags<QMessageBox::StandardButton> buttons = QMessageBox::Ok){ 
    QMessageBox *messageBox = new QMessageBox(icon, title, text, buttons, parent); 
    messageBox->open(NULL, NULL); 
    QObject::connect(messageBox, &QMessageBox::finished, [messageBox, lambda](){ 
     if(messageBox->clickedButton() == messageBox->button(QMessageBox::Ok)){ 
      lambda(QMessageBox::Ok); 
     } 
     else if(messageBox->clickedButton() == messageBox->button(QMessageBox::Open)){ 
      lambda(QMessageBox::Open); 
     } 
     else if(messageBox->clickedButton() == messageBox->button(QMessageBox::Save)){ 
      lambda(QMessageBox::Save); 
     } 
     else if(messageBox->clickedButton() == messageBox->button(QMessageBox::Cancel)){ 
      lambda(QMessageBox::Cancel); 
     } 
     else if(messageBox->clickedButton() == messageBox->button(QMessageBox::Close)){ 
      lambda(QMessageBox::Close); 
     } 
     else if(messageBox->clickedButton() == messageBox->button(QMessageBox::Discard)){ 
      lambda(QMessageBox::Discard); 
     } 
     else if(messageBox->clickedButton() == messageBox->button(QMessageBox::Apply)){ 
      lambda(QMessageBox::Apply); 
     } 
     else if(messageBox->clickedButton() == messageBox->button(QMessageBox::Reset)){ 
      lambda(QMessageBox::Reset); 
     } 
     else if(messageBox->clickedButton() == messageBox->button(QMessageBox::RestoreDefaults)){ 
      lambda(QMessageBox::RestoreDefaults); 
     } 
     else if(messageBox->clickedButton() == messageBox->button(QMessageBox::Help)){ 
      lambda(QMessageBox::Help); 
     } 
     else if(messageBox->clickedButton() == messageBox->button(QMessageBox::SaveAll)){ 
      lambda(QMessageBox::SaveAll); 
     } 
     else if(messageBox->clickedButton() == messageBox->button(QMessageBox::Yes)){ 
      lambda(QMessageBox::Yes); 
     } 
     else if(messageBox->clickedButton() == messageBox->button(QMessageBox::YesToAll)){ 
      lambda(QMessageBox::YesToAll); 
     } 
     else if(messageBox->clickedButton() == messageBox->button(QMessageBox::No)){ 
      lambda(QMessageBox::No); 
     } 
     else if(messageBox->clickedButton() == messageBox->button(QMessageBox::NoToAll)){ 
      lambda(QMessageBox::NoToAll); 
     } 
     else if(messageBox->clickedButton() == messageBox->button(QMessageBox::Abort)){ 
      lambda(QMessageBox::Abort); 
     } 
     else if(messageBox->clickedButton() == messageBox->button(QMessageBox::Retry)){ 
      lambda(QMessageBox::Retry); 
     } 
     else if(messageBox->clickedButton() == messageBox->button(QMessageBox::Ignore)){ 
      lambda(QMessageBox::Ignore); 
     } 
     else{ 
      lambda(QMessageBox::NoButton); 
     } 
    }); 
} 

以下のコードは、ユーザーに尋ねます。ユーザーが「はい」をクリックすると、「Hello World!」というダイアログボックスが開きます。そうでない場合は何も起こりません。

IrrlichtWidget myWidget = new IrrlichtWidget; //IrrlichtWidget is the class mentioned in the question 
showMessageBox([](QMessageBox::StandardButton result){ 
    if(result == QMessageBox::Yes){ 
     showMessageBox([](QMessageBox::StandardButton){}, myWidget, "Hello", "Hello world!"); 
    } 
}, myWidget, "Title", "Do you want to open a new dialog box?", QMessageBox::Question, QMessageBox::Yes | QMessageBox::No); 
関連する問題