是否有信号告诉他们什么时候显示'功能完成?
我的代码中有问题:如果我写:
QMainWinObj.show();
QMainWinObj.someGuiFunc();
代码不起作用。但是,如果我写:
QMainWinObj.show();
sleep(3000);
QMainWinObj.someGuiFunc();
确实如此。
所以我认为问题是'显示'在我打电话给someGuiFunc'之前,我没有完成它的jub。这就是为什么我想要某种表示“显示”的标志的原因。结束了..
答案 0 :(得分:5)
这可能有点过时,但除了一个以外没有其他人回答: 由于没有“显示”信号,我建议覆盖show事件,如下所示:
在你的mainwindow.cpp文件中:
void MainWindow::show()
{
QMainWindow::show();
QApplication::processEvents();
emit windowShown();
}
在mainwindow.h文件中,MainWindow声明中的某个地方:
...
class MainWindow: public QMainWindow
{
...
signals:
void windowShown();
...
}
...
然后,当您转到设计器时,右键单击主窗口(对象树的顶部),然后选择“更改信号/插槽”。在“信号”框中,单击“+”按钮,您需要添加“windowShown()”,然后按Enter,然后按OK按钮(请注意,elipses“...”表示其他代码是已经在你的标题中。)
就是这样 - 你现在可以随时使用信号/插槽编辑器将插槽连接到'windowShown'信号。现在,如果你想要更像微软的“Loaded”事件,我认为在.NET中使用它你将需要创建一些实例变量并标记它,以便每次显示窗口时,它都不会被发出,例如:
void MainWindow::show()
{
QMainWindow::show();
QApplication::processEvents();
emit windowShown();
if (firstTimeShown == true)
{
emit windowLoaded();
firstTimeShown = false;
}
}
另外,不要忘记在构造函数中将变量初始化为“true”:
MainWindow::MainWindow(QObject* parent)
...
{
firstTimeShown = true; // put this somewhere before ui->setupUi()
}
如果您决定将其放入初始化列表中,请确保其顺序正确。如果变量没有按照类的标题中声明的从上到下的方式实例化,编译器会抱怨。
现在,确保在标题中定义firstTimeShown时,将其设为私有。不要忘记增加的信号:
class MainWindow : public QMainWindow
{
...
signals:
void windowLoaded();
void windowShown();
private:
bool firstTimeShown;
...
就是这样。凭借信号和插槽的灵活性,它很容易模仿您从Windows窗体或MFC中找到的任何事件。程序员只需要花一点力气就可以了。一旦掌握了它,它就会成为第二天性。
注意:可能是优化或更好,更精确的方式使“加载”和“显示”信号执行但我为了简单起见留下了这样的事情。回到手头的问题,调用QApplication :: processEvents()很可能是你想要做的而不是等待一段固定的时间,因为谁知道如果用户运行100个其他东西需要多长时间希望有所帮助,包括额外的解释,希望它可以给你一个更好的方法来做你想做的事情,而不是等待做某事,'知道'它完成了是一个更好的选择。
答案 1 :(得分:3)
没有这样的信号,但有了QMainWindow子类,你可以覆盖showEvent事件。
void MainWindow::showEvent(QShowEvent *){
//your code
}
此处有更多信息:http://qt-project.org/doc/qt-4.8/qwidget.html#showEvent
请注意,每次要显示窗口时都会调用它。
答案 2 :(得分:1)
问题可以在没有子类化的情况下决定,只需安装这样的事件过滤器:
class CWidgetIsPainting_EF : public QObject
{
bool m_bIsPainted = false;
public:
CWidgetIsPainting_EF( QObject * parent = 0 ) : QObject (parent) { }
inline bool IsPainted() const { return m_bIsPainted; }
inline void setIsPainted( bool bIsPainted ) { m_bIsPainted = bIsPainted; }
protected:
bool eventFilter( QObject * obj, QEvent *event )
{
if (event->type() == QEvent::Paint)
{
m_bIsPainted = true;
return true;
};
return QObject::eventFilter(obj, event);
}
};
... ...
CWidgetIsPainting_EF * pPaintingEF = new CWidgetIsPainting_EF( m_pWidget );
m_pWidget->installEventFilter( pPaintingEF );
... ...
while ( !pPaintingEF->IsPainted() )
QApplication::processEvents();
答案 3 :(得分:0)
覆盖bool event(QEvent *event)
并捕获Paint事件。至少在Windows上适用于我。
// MainWindow.h
class MainWindow : public QMainWindow
{
...
bool event(QEvent *event) override;
void functionAfterShown();
...
bool functionAfterShownCalled = false;
...
}
// MainWindow.cpp
bool MainWindow::event(QEvent *event)
{
const bool ret_val = QMainWindow::event(event);
if(!functionAfterShownCalled && event->type() == QEvent::Paint)
{
functionAfterShown();
functionAfterShownCalled = true;
}
return ret_val;
}