如何获得通知"这是什么"单击窗口小部件上的按钮?

时间:2017-05-19 15:13:17

标签: c++ qt qt5

当我按下[?]"这是什么?"标题栏中的按钮,我应该检查哪个信号?

   Qt::WindowFlags flags;

   flags |= Qt::CustomizeWindowHint;    // Remove all previous windows hints

   // Restore previous hints
   flags |= Qt::Window;
   flags |= Qt::WindowTitleHint;
   flags |= Qt::WindowSystemMenuHint;
   //flags |= Qt::WindowMinimizeButtonHint;    // Hides [?]
   //flags |= Qt::WindowMaximizeButtonHint;    // Hides [?]
   flags |= Qt::WindowCloseButtonHint;

   // Add new hints
   flags |= Qt::WindowContextHelpButtonHint;

   setWindowFlags(flags);

   connect(this, ???, this, MainWindow::TestSlot());

1 个答案:

答案 0 :(得分:1)

  

按下[?]按钮时,我需要调用一个函数(例如写一条日志消息)。

当分别输入和离开What's This模式时,顶级窗口会收到QEvent::EnterWhatsThisModeQEvent::LeaveWhatsThisMode个事件。

当窗口小部件收到事件时,您可以将事件转换为信号,例如使用该小部件上安装的event signaler

或者,如果您想自动捕获所有窗口上的事件,而不在每个顶级窗口小部件上安装信号器,则可以在QApplication对象本身上安装信号器。

以下是一个完整的例子:

// https://github.com/KubaO/stackoverflown/tree/master/questions/whatsthis-bypass-44073556
#include <QtWidgets>

// See https://stackoverflow.com/a/32027028/1329652
class WhatsThisSignaler : public QObject {
   Q_OBJECT
   bool eventFilter(QObject * obj, QEvent * ev) override {
      if (!obj->isWidgetType())
         return false;
      auto widget = static_cast<QWidget*>(obj);
      if (!widget->isWindow())
         return false;
      switch (ev->type()) {
      case QEvent::EnterWhatsThisMode:
      case QEvent::LeaveWhatsThisMode:
         emit whatsThisEvent(widget, ev);
         break;
      default:
         break;
      }
      return false;
   }
public:
   Q_SIGNAL void whatsThisEvent(QWidget *, QEvent *);
   WhatsThisSignaler(QObject * parent = {}) : QObject(parent) {}
   void installOn(QWidget * widget) {
      widget->installEventFilter(this);
   }
   void installOn(QCoreApplication * app) {
      app->installEventFilter(this);
   }
};

// See https://stackoverflow.com/q/22535469/1329652
template<typename EnumType> QString toName(EnumType enumValue)
{
    auto * enumName = qt_getEnumName(enumValue);
    auto * metaObject = qt_getEnumMetaObject(enumValue);
    QString name;
    if (metaObject) {
        auto enumIndex = metaObject->indexOfEnumerator(enumName);
        name = metaObject->enumerator(enumIndex).valueToKey(enumValue);
    }
    if (name.isEmpty())
       name = QString::number((int)enumValue);
    return name;
}

int main(int argc, char ** argv) {
   QApplication app{argc, argv};
   WhatsThisSignaler sig;
   QPlainTextEdit w;
   w.setWindowFlags(Qt::WindowContextHelpButtonHint | Qt::WindowCloseButtonHint);
   w.setMinimumSize(200, 200);
   w.setReadOnly(true);
   w.show();
   sig.installOn(&w);
   QObject::connect(&sig, &WhatsThisSignaler::whatsThisEvent, &w, [&w](QWidget*widget, QEvent*ev){
      w.appendPlainText(QStringLiteral("%1(0x%2) \"%3\" QEvent::%4")
                        .arg(widget->metaObject()->className())
                        .arg((uintptr_t)widget, 0, 16)
                        .arg(widget->objectName())
                        .arg(toName(ev->type())));
   });
   return app.exec();
}

#include "main.moc"