0

QMainWindow に GLWidget サブクラス ウィジェットを含む Qt/OpenGL/OpenCL アプリケーションがあります。QMainWindow のメニューから GLWidget に (キーを押して) ズーム機能を追加したいと思います。

もともと、次のようにGLWidgetから直接ズームイン/ズームアウトしました(GLWidget.cpp):

void GLWidget::keyPressEvent(QKeyEvent* event) 
{
  switch(event->key()) {
    case Qt::Key_W:
      zoomScale(zoomFactor_in);
      zoomGlobal = 1.0f / zoomFactor_in;
      break;
    case Qt::Key_X:
      zoomScale(zoomFactor_out);
      zoomGlobal = 1.0f / zoomFactor_out;
      break;        
    default:
      event->ignore();
      break;
  }
}

そこで、QMainWindow メニューのアクションからこの機能を追加するために、シグナル/スロット (MainWindow.cpp) を作成します。

void Ui_MainWindow::createSignals()
{ 
...
  connect(actionZoom_In, SIGNAL(triggered()), this, SLOT(zoomIn()));     
  connect(actionZoom_Out, SIGNAL(triggered()), this, SLOT(zoomOut()));  

}

次のスロットを使用します(キープレス信号をGLwidget「widget_2」に送信するためにこの方法を試しています):

void Ui_MainWindow::zoomIn()
{
  QKeyEvent event1 = QKeyEvent(QEvent::KeyPress, Qt::Key_W, Qt::NoModifier);
  QApplication::sendEvent(widget_2, &event1);  
}

void Ui_MainWindow::zoomOut()
{
  QKeyEvent event2 = QKeyEvent(QEvent::KeyPress, Qt::Key_X, Qt::NoModifier);
  QApplication::sendEvent(widget_2, &event2);
}

widget_2 は、KeyPress 'X' または 'W' を送信する GLWidget_2 です。

残念ながら、これは機能しません。「X」または「W」を押すとセグメンテーション違反が発生し、その理由がわかりません。

バックトレースは次のとおりです。

(gdb) bt
#0  0x00007ffff6c70e80 in ?? () from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#1  0x00007ffff6c7127f in QMainWindow::event(QEvent*) () from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#2  0x00007ffff685d70c in QApplicationPrivate::notify_helper(QObject*, QEvent*) () from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#3  0x00007ffff6862704 in QApplication::notify(QObject*, QEvent*) () from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#4  0x00007ffff6328b5e in QCoreApplication::notifyInternal(QObject*, QEvent*) () from /usr/lib/x86_64-linux-gnu/libQtCore.so.4
#5  0x00007ffff688f8cc in ?? () from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#6  0x00007ffff6863869 in QApplication::notify(QObject*, QEvent*) () from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#7  0x00007ffff6328b5e in QCoreApplication::notifyInternal(QObject*, QEvent*) () from /usr/lib/x86_64-linux-gnu/libQtCore.so.4
#8  0x000000000047af4e in Ui_MainWindow::zoomIn() ()
#9  0x00007ffff633e54f in QMetaObject::activate(QObject*, QMetaObject const*, int, void**) () from /usr/lib/x86_64-linux-gnu/libQtCore.so.4
#10 0x00007ffff6857502 in QAction::triggered(bool) () from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#11 0x00007ffff68576f0 in QAction::activate(QAction::ActionEvent) () from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#12 0x00007ffff6857857 in QAction::event(QEvent*) () from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#13 0x00007ffff685d70c in QApplicationPrivate::notify_helper(QObject*, QEvent*) () from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#14 0x00007ffff6861b8a in QApplication::notify(QObject*, QEvent*) () from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#15 0x00007ffff6328b5e in QCoreApplication::notifyInternal(QObject*, QEvent*) () from /usr/lib/x86_64-linux-gnu/libQtCore.so.4
#16 0x00007ffff688e474 in ?? () from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#17 0x00007ffff688f983 in ?? () from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#18 0x00007ffff6863869 in QApplication::notify(QObject*, QEvent*) () from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#19 0x00007ffff6328b5e in QCoreApplication::notifyInternal(QObject*, QEvent*) () from /usr/lib/x86_64-linux-gnu/libQtCore.so.4
#20 0x000000000047af4e in Ui_MainWindow::zoomIn() ()
#21 0x00007ffff633e54f in QMetaObject::activate(QObject*, QMetaObject const*, int, void**) () from /usr/lib/x86_64-linux-gnu/libQtCore.so.4
#22 0x00007ffff6857502 in QAction::triggered(bool) () from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#23 0x00007ffff68576f0 in QAction::activate(QAction::ActionEvent) () from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#24 0x00007ffff6857857 in QAction::event(QEvent*) () from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#25 0x00007ffff685d70c in QApplicationPrivate::notify_helper(QObject*, QEvent*) () from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#26 0x00007ffff6861b8a in QApplication::notify(QObject*, QEvent*) () from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#27 0x00007ffff6328b5e in QCoreApplication::notifyInternal(QObject*, QEvent*) () from /usr/lib/x86_64-linux-gnu/libQtCore.so.4
#28 0x00007ffff688e474 in ?? () from /usr/lib/x86_64-linux-gnu/libQtGui.so.4

...

MainWindow メニューから actionZoom_In/Out をクリックすると同じ問題が発生しますが、2 回目のクリックで segfault が発生します。

誰が何が悪いのか見ることができますか?

4

2 に答える 2

0

イベント (任意のポインター tbh) が nullptr であるかどうかを常にチェックします。event->ignore() でも nullptr で segfault が発生します。(そして、そうです。Qt の関数は nullptr イベントで呼び出されることがあります)

于 2021-06-15T07:21:56.480 に答える