【问题标题】:QWidget is not updating when using show instead of exec使用 show 而不是 exec 时 QWidget 不更新
【发布时间】:2013-06-12 12:11:51
【问题描述】:

在我的项目中,我需要在我的 Mfc 应用程序顶部创建一个非阻塞 QWizard。为此,我按照此处的说明进行操作 (link)

这样做有一个奇怪的副作用,当我单击 QWizardPage 中的 QRadioButton 时,我的 UI 似乎没有正确更新。请参阅以下屏幕截图:

1-我的 QWizard 的第一步。一切看起来都不错

2-我点击了一个 QRadioButton。看,“下一步”按钮处于一种奇怪的状态。

3-我点击了第二个 QRadioButton。看,两个 QRadioButton 看起来都被选中了。 (是的,它们是互斥的!

4-现在,如果我在“鼠标悬停”、“下一步”按钮和 QRadioButton 上进行操作,这会强制更新,而我的 UI 很好

我的问题是:如何在使用 show 而不是 exec 时正确更新我的 UI? (我确实尝试了 exec 并且我的 UI 正在正确更新)

如果我使用 show,我猜主线程不会更新我的 UI?

谢谢。

编辑

这是实例化向导的函数代码:

void QtMfcFacade::startDevicesConfigurationWizard(HWND hWnd)
{
    QWinWidget* win = new QWinWidget( hWnd );
    win->showCentered();
    DevicesConfigurationWizard *devicesConfigurationWizardUI = new DevicesConfigurationWizard(win);
    devicesConfigurationWizardUI->setModal(true);
    devicesConfigurationWizardUI->show();
}

以下是我的 QWizard 课程:

DevicesConfigurationWizard::DevicesConfigurationWizard(QWidget *parent, Qt::WFlags flags)
    : QWizard(parent, flags),
{
    ui.setupUi(this);
    this->setWindowFlags( ( (this->windowFlags() | Qt::CustomizeWindowHint)
                       & ~Qt::WindowCloseButtonHint & ~Qt::WindowContextHelpButtonHint) );
    this->setAttribute( Qt::WA_DeleteOnClose, true );
    connect(this, SIGNAL(currentIdChanged(int)), this, SLOT(onClick(int)));
}

void DevicesConfigurationWizard::onClick(int pageId)
{
    if (m_currentPageId < pageId)
    {        
        //user clicked next button.
        switch (pageId)
        {
            case PAGE_NUMBER_SINGLE_USER:
            {
                setupSingleUserPage();
                break;
            }
            default :
            {
                //problem!!!
            }
        }
        m_currentPageId = pageId;
    }
}

void DevicesConfigurationWizard::onRadioButtonClick()
{
    this->button(this->NextButton)->setEnabled(true);
    this->button(this->FinishButton)->setEnabled(true);
}

void DevicesConfigurationWizard::setupSingleUserPage()
{
    this->button(this->NextButton)->setEnabled(false);
    int newPositionY = 0;
        QVBoxLayout* layout = ui.wpSINGLE_USER->findChild<QVBoxLayout*>("verticalLayout");
        for (vector<Events::VCS::PnPDevice>::const_iterator it=m_devices.begin(); it!=m_devices.end(); it++)
        {
            if (it->type == Events::VCS::HEADSET)
            {
                //add a radio button
                stringstream text;
                text <<  (it->name) << " " << (it->serialNumber) ;
                QRadioButton* radioButton = new QRadioButton(this->ui.wpSINGLE_USER);
                radioButton->setGeometry(X, Y + newPositionY, WIDHT, HEIGHT);
                radioButton->setText(text.str().c_str());
                radioButton->setIconSize(QSize(HEIGHT,HEIGHT));
                newPositionY = newPositionY + HEIGHT;
                layout->insertWidget(0, radioButton);
                connect(radioButton, SIGNAL(clicked()), this, SLOT(onRadioButtonClick()));
            }
    }
}

EDIT 尝试强制更新目前未解决问题

void DevicesConfigurationWizard::onRadioButtonClick()
{
    this->button(this->NextButton)->setEnabled(true);
    this->button(this->FinishButton)->setEnabled(true);
    QWidget::update();
    this->update();
    this->button(this->NextButton)->update();
    QList<QRadioButton*> listButton = ui.wpSINGLE_USER->findChildren<QRadioButton*>();
    listButton[0]->update();
    listButton[1]->update();
    QApplication::processEvents();
}

【问题讨论】:

  • 应该没问题。 show() 只是调用,当您不希望窗口为模态时。截图很好,但我想要你的一些代码......
  • @Zaiborg 代码已添加。我觉得问题可能是主要应用程序是Mfc。我用 QtCreator 做了一个快速测试,你是对的,show() 不是问题。但就像我在上面的例子中说的那样,使用 exec 解决了问题(但它带来了一个新问题,我正在阻塞我的 Mfc 应用程序)

标签: qt qt4 qwidget qt-mfc-migration


【解决方案1】:

也许这会有所帮助:

void DevicesConfigurationWizard::setupSingleUserPage()
{
    this->button(this->NextButton)->setEnabled(false);
    int newPositionY = 0;
        QVBoxLayout* layout = ui.wpSINGLE_USER->findChild<QVBoxLayout*>("verticalLayout");
        QButtonGroup* group = new QButtonGroup(this); // add this
        for (vector<Events::VCS::PnPDevice>::const_iterator it=m_devices.begin(); it!=m_devices.end(); it++)
        {
            if (it->type == Events::VCS::HEADSET)
            {
                //add a radio button
                stringstream text;
                text <<  (it->name) << " " << (it->serialNumber) ;
                QRadioButton* radioButton = new QRadioButton(this->ui.wpSINGLE_USER);
                group->addButton(radioButton); // and add this
                radioButton->setGeometry(X, Y + newPositionY, WIDHT, HEIGHT);
                radioButton->setText(text.str().c_str());
                radioButton->setIconSize(QSize(HEIGHT,HEIGHT));
                newPositionY = newPositionY + HEIGHT;
                layout->insertWidget(0, radioButton);
                connect(radioButton, SIGNAL(clicked()), this, SLOT(onRadioButtonClick()));
            }
    }
}

当我尝试在上下文菜单中插入单选按钮时遇到了类似的问题。

苏长在

【讨论】:

  • 不幸的是,这并没有解决问题。此外,问题不仅在于 QRadioButton,还在于 QPushButton(“下一步”按钮未更新)。谢谢帮助
  • 使用QWidget::update()的显式调用?可能不是最性感的方式,但您可以尝试在单击单选按钮时使其适应...
  • 两者都不是 :( 查看我更新的帖子,我尝试了所有可能的方法来强制更新。我真的不明白:/
【解决方案2】:

问题来自我的 Mfc 应用程序。计时器每 100 毫秒向事件循环发送一个计时器事件,因此,我的 Qt 应用程序无法正确更新。所以,我所做的就是将 QCoreApplication::processEvents() 添加到 OnTimer 中,在 Mfc 应用程序上。

这样,QCoreApplication::processEvents 每隔 100 milisedonds 就会被调用一次,我的 Qt UI 现在已正确更新。

【讨论】:

    猜你喜欢
    • 2014-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多