我在Qt上下文中使用Irrlicht。为此,我有一个IrrlichtWidget
类,它在QWidget中显示一个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
之前,这很好用。当我使用这个类编程并希望使用QMessageBox
时,我注意到每当消息框打开时,Irrlicht小部件变黑。为了找出发生了什么,我在Irrlicht主循环中插入了QMessageBox
,使它看起来像这样:
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");
});
当我这样做时,背景是黑色的:
要进行比较,这是完全相同的程序,唯一的区别是它没有QMessageBox
:
我尝试将QMessageBox
放在Irrlicht的主循环中,在开头,末尾,中间,它总是做同样的事情。它为每种Qt对话框执行此操作:QMessageBox
,QFileDialog
等。
我还尝试删除构造函数中的setAttribute(Qt::WA_OpaquePaintEvent)
行,然后背景为米色而不是黑色。颜色不一样,但问题仍然存在。
似乎QMessageBox
以某种方式删除了Irrlicht小部件的内容。它为什么这样做?我该如何解决?
答案 0 :(得分: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);