QPushButton застревает при нажатии рисования, когда передача фокуса на кнопку прерывается - PullRequest
1 голос
/ 21 января 2011

У меня есть несколько форм с полями ввода, которые предоставляют пользователю предупреждения, когда поля теряют фокус (если что-то не так, конечно). Для этого я создал свой собственный элемент управления, который наследуется от QLineEdit. Для этого вопроса рассмотрим чрезвычайно простое поле, которое будет открывать окно сообщения всякий раз, когда фокус теряется, когда в элементе управления есть текст. Фактические элементы управления имеют больше логики, но все должны открывать окно сообщения. (Перекрестно размещено на qtcentre.org)

class test_line_edit : public QLineEdit
{
  Q_OBJECT

public:
  test_line_edit(QWidget * parent = 0) : QLineEdit(parent)
  {}

  ~test_line_edit(){}

protected:  
  virtual void focusOutEvent(QFocusEvent * e)
  {
    if(!text().isEmpty())
    {
      QMessageBox msg;
      msg.setText(tr("Test"));
      msg.exec();
      setFocus(Qt::OtherFocusReason);
    }
    else
    {
      QLineEdit::focusOutEvent(e);
    }
  }

};

Теперь скажите, что у меня есть простая форма с одним из этих элементов управления и QPushButton. Если пользователь вводит элемент управления, а затем нажимает кнопку, появляется окно сообщения, но кнопка застревает и выглядит как нажатая. Как я могу остановить это? Насколько я могу судить, нажатый сигнал QPushButton срабатывает, но это все, что я слышу от кнопки. Поскольку эти элементы управления test_line_edit будут использоваться повсеместно в самых разных формах, я надеюсь, что есть кое-что, что я могу изменить в классе test_line_edit, чтобы исправить проблему. Запуск Qt 4.7.0 в Windows XP с использованием Visual Studio 2010.

Я видел эту ошибку и не уверен, что она связана, поскольку это другая платформа, и я на самом деле не удерживаю кнопку нажатой: http://bugreports.qt -project.org / browse / QTBUG-7901

Вот полная программа, которая демонстрирует проблему (предупреждение: некоторый код, сгенерированный из плагина Qt VS)

main.h:

#include <QtGui/QMainWindow>

#include <QtCore/QVariant>
#include <QtGui/QAction>
#include <QtGui/QApplication>
#include <QtGui/QButtonGroup>
#include <QtGui/QHeaderView>
#include <QtGui/QMainWindow>
#include <QtGui/QMenuBar>
#include <QtGui/QPushButton>
#include <QtGui/QStatusBar>
#include <QtGui/QToolBar>
#include <QtGui/QVBoxLayout>
#include <QtGui/QWidget>

#include <QLineEdit>
#include <QMessageBox>

class test_line_edit : public QLineEdit
{
  Q_OBJECT

public:
  test_line_edit(QWidget * parent = 0) : QLineEdit(parent)
  {}

  ~test_line_edit(){}

protected:  
  virtual void focusOutEvent(QFocusEvent * e)
  {
    if(!text().isEmpty())
    {
      QMessageBox msg;
      msg.setText(tr("Test"));
      msg.exec();
      //setFocus(Qt::OtherFocusReason);
    }
    else
    {
      QLineEdit::focusOutEvent(e);
    }

    QLineEdit::focusOutEvent(e);
  }

};

QT_BEGIN_NAMESPACE

class Ui_btn_drawing_testClass
{
public:
    QWidget *centralWidget;
    QVBoxLayout *verticalLayout;
    test_line_edit *line_edit;
    QPushButton *btn;
    QMenuBar *menuBar;
    QToolBar *mainToolBar;
    QStatusBar *statusBar;

    void setupUi(QMainWindow *btn_drawing_testClass)
    {
        if (btn_drawing_testClass->objectName().isEmpty())
            btn_drawing_testClass->setObjectName(QString::fromUtf8("btn_drawing_testClass"));
        btn_drawing_testClass->resize(167, 127);
        centralWidget = new QWidget(btn_drawing_testClass);
        centralWidget->setObjectName(QString::fromUtf8("centralWidget"));
        verticalLayout = new QVBoxLayout(centralWidget);
        verticalLayout->setSpacing(6);
        verticalLayout->setContentsMargins(11, 11, 11, 11);
        verticalLayout->setObjectName(QString::fromUtf8("verticalLayout"));
        line_edit = new test_line_edit(centralWidget);
        line_edit->setObjectName(QString::fromUtf8("line_edit"));

        verticalLayout->addWidget(line_edit);

        btn = new QPushButton(centralWidget);
        btn->setObjectName(QString::fromUtf8("btn"));

        verticalLayout->addWidget(btn);

        btn_drawing_testClass->setCentralWidget(centralWidget);
        menuBar = new QMenuBar(btn_drawing_testClass);
        menuBar->setObjectName(QString::fromUtf8("menuBar"));
        menuBar->setGeometry(QRect(0, 0, 167, 20));
        btn_drawing_testClass->setMenuBar(menuBar);
        mainToolBar = new QToolBar(btn_drawing_testClass);
        mainToolBar->setObjectName(QString::fromUtf8("mainToolBar"));
        btn_drawing_testClass->addToolBar(Qt::TopToolBarArea, mainToolBar);
        statusBar = new QStatusBar(btn_drawing_testClass);
        statusBar->setObjectName(QString::fromUtf8("statusBar"));
        btn_drawing_testClass->setStatusBar(statusBar);

        retranslateUi(btn_drawing_testClass);

        QMetaObject::connectSlotsByName(btn_drawing_testClass);
    } // setupUi

    void retranslateUi(QMainWindow *btn_drawing_testClass)
    {
        btn_drawing_testClass->setWindowTitle(QApplication::translate("btn_drawing_testClass", "btn_drawing_test", 0, QApplication::UnicodeUTF8));
        btn->setText(QApplication::translate("btn_drawing_testClass", "PushButton", 0, QApplication::UnicodeUTF8));
    } // retranslateUi

};

namespace Ui {
    class btn_drawing_testClass: public Ui_btn_drawing_testClass {};
} // namespace Ui

QT_END_NAMESPACE

class btn_drawing_test : public QMainWindow
{
    Q_OBJECT

public:
  btn_drawing_test(QWidget *parent = 0, Qt::WFlags flags = 0): QMainWindow(parent, flags)
  {
    ui.setupUi(this);
  }
  ~btn_drawing_test(){}

private:
    Ui::btn_drawing_testClass ui;

protected slots:
  void on_btn_clicked()
  {
    int breakpoint = 5;
  }
  void on_btn_pressed()
  {
    int breakpoint = 5;
  }    
  void on_btn_toggled(bool)
  {
    int breakpoint = 5;
  }
};

main.cpp:

#include <QtGui/QApplication>
#include "main.h"



int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    btn_drawing_test w;
    w.show();
    return a.exec();
}

Спасибо за вашу помощь и, пожалуйста, дайте мне знать, если я могу предоставить дополнительную информацию.

1 Ответ

0 голосов
/ 22 января 2011

Я внес некоторые изменения в ваш класс редактирования строк, посмотрите, решит ли он проблему:

class test_line_edit : public QLineEdit
{
    Q_OBJECT

public:
    test_line_edit(QWidget * parent = 0) : QLineEdit(parent) {}
    ~test_line_edit(){}

protected:
    virtual void focusOutEvent(QFocusEvent * e)
    {
        QLineEdit::focusOutEvent(e);
        QEvent *event = new QEvent(QEvent::User);
        QApplication::postEvent(this, event);
    }

    virtual void customEvent(QEvent * event)
    {
        QLineEdit::customEvent(event);
        if (event->type()==QEvent::User)
        {
            QMessageBox msg;
            msg.setText(tr("Test"));
            msg.exec();
            setFocus(Qt::OtherFocusReason);
        }
    }
};

Вместо отображения модального окна в методе focusOutEvent я отправил событие в очередь событий. Это нормально работало на моей Ubuntu, также не ожидайте проблем с Windows.

надеюсь, это поможет, с уважением

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...