Segfault при нажатии меню в QT - PullRequest
0 голосов
/ 03 мая 2018

Я довольно новичок в разработке QT и пытаюсь создать свое первое окно с меню. Проблема в том, что я получаю ошибку сегментации всякий раз, когда я на самом деле нажимаю на меню «Файл» при попытке его отладки.

Это QT 5.10, работающий на Fedora Linux 64-bit

Мой заголовочный файл имеет:

private:
    QApplication app;
    Ui::MainWindow ui;
    QMainWindow mainWindow;

public:
    explicit ProgName(int argc, char *argv[], QObject *parent = nullptr);
    int run();

... а остальное просто стандартный шаблон QT, для краткости опущен. Мой основной исходный файл:

#include "progname.h"

int main(int argc, char *argv[])
{
    ProgName pn(argc, argv, nullptr);

    return pn.run();
}

ProgName::ProgName(int argc, char *argv[], QObject *parent) :
    QObject(parent),
    app(argc, argv)
{
    ui.setupUi(&mainWindow);
}

int ProgName::run()
{
    mainWindow.show();

    return app.exec();
}

И действительно длинный файл UI, созданный с помощью QT creator:

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>MainWindow</class>
 <widget class="QMainWindow" name="MainWindow">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>400</width>
    <height>300</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>MainWindow</string>
  </property>
  <widget class="QWidget" name="centralWidget">
   <layout class="QFormLayout" name="formLayout">
    <item row="0" column="0">
     <widget class="QTreeView" name="mainTreeView"/>
    </item>
   </layout>
  </widget>
  <widget class="QMenuBar" name="mainMenuBar">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>400</width>
     <height>28</height>
    </rect>
   </property>
   <widget class="QMenu" name="menuFile">
    <property name="title">
     <string>File</string>
    </property>
   </widget>
   <addaction name="menuFile"/>
  </widget>
 </widget>
 <layoutdefault spacing="6" margin="11"/>
 <resources/>
 <connections/>
</ui>

Есть идеи?

Редактировать: Вот трассировка стека:

1  __strlen_avx2                                                                                                                                0x7ffff5832c37 
2  QCoreApplication::arguments()                                                                                                                0x7ffff6a7a63b 
3  argv0BaseName()                                                                                                                              0x7fffe88d0101 
4  QXcbIntegration::wmClass() const                                                                                                             0x7fffe88d05fd 
5  QXcbWindow::create()                                                                                                                         0x7fffe88e596b 
6  QXcbIntegration::createPlatformWindow(QWindow *) const                                                                                       0x7fffe88d153e 
7  QWindowPrivate::create(bool, unsigned long long)                                                                                             0x7ffff6fd32fe 
8  QWidgetPrivate::create_sys(unsigned long long, bool, bool)                                                                                   0x7ffff7714ced 
9  QWidget::create(unsigned long long, bool, bool)                                                                                              0x7ffff77153ad 
10 QMenuPrivate::adjustMenuScreen(QPoint const&)                                                                                                0x7ffff785bf68 
11 QMenu::popup(QPoint const&, QAction *)                                                                                                       0x7ffff785f801 
12 QMenuBarPrivate::popupAction(QAction *, bool)                                                                                                0x7ffff786c402 
13 QMenuBarPrivate::setCurrentAction(QAction *, bool, bool)                                                                                     0x7ffff786e508 
14 QMenuBar::mousePressEvent(QMouseEvent *)                                                                                                     0x7ffff786ee72 
15 QWidget::event(QEvent *)                                                                                                                     0x7ffff7722baf 
16 QMenuBar::event(QEvent *)                                                                                                                    0x7ffff787014b 
17 QApplicationPrivate::notify_helper(QObject *, QEvent *)                                                                                      0x7ffff76e392c 
18 QApplication::notify(QObject *, QEvent *)                                                                                                    0x7ffff76eb6cf 
19 QCoreApplication::notifyInternal2(QObject *, QEvent *)                                                                                       0x7ffff6a76be7 
20 QApplicationPrivate::sendMouseEvent(QWidget *, QMouseEvent *, QWidget *, QWidget *, QWidget * *, QPointer<QWidget>&, bool)                   0x7ffff76ea6a2 
21 QWidgetWindow::handleMouseEvent(QMouseEvent *)                                                                                               0x7ffff773d47b 
22 QWidgetWindow::event(QEvent *)                                                                                                               0x7ffff773fb1f 
23 QApplicationPrivate::notify_helper(QObject *, QEvent *)                                                                                      0x7ffff76e392c 
24 QApplication::notify(QObject *, QEvent *)                                                                                                    0x7ffff76eb174 
25 QCoreApplication::notifyInternal2(QObject *, QEvent *)                                                                                       0x7ffff6a76be7 
26 QGuiApplicationPrivate::processMouseEvent(QWindowSystemInterfacePrivate::MouseEvent *)                                                       0x7ffff6fc98a3 
27 QGuiApplicationPrivate::processWindowSystemEvent(QWindowSystemInterfacePrivate::WindowSystemEvent *)                                         0x7ffff6fcb495 
28 QWindowSystemInterface::sendWindowSystemEvents(QFlags<QEventLoop::ProcessEventsFlag>)                                                        0x7ffff6fa479b 
29 userEventSourceDispatch(_GSource *, int ( *)(void *), void *)                                                                                0x7fffe892cb60 
30 g_main_context_dispatch                                                                                                                      0x7ffff2195b77 
31 g_main_context_iterate.isra                                                                                                                  0x7ffff2195f20 
32 g_main_context_iteration                                                                                                                     0x7ffff2195fac 
33 QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>)                                                                   0x7ffff6ac7c2f 
34 QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>)                                                                                      0x7ffff6a7596a 
35 QCoreApplication::exec()                                                                                                                     0x7ffff6a7e094 
36 ProgName::run                                                                                                            progname.cpp 21 0x401aaf       
37 main                                                                                                                       progname.cpp 7  0x401961       

1 Ответ

0 голосов
/ 03 мая 2018

Пожалуйста, посмотрите на конструкторы QCoreApplication и QApplication .

Конструкторы ожидают, что аргумент argc будет ссылкой на целое число .

В вашем случае вы передаете аргумент argc по значению конструктору вашего класса ProgName. Внутри вы передаете ссылку на это (локальное) значение в конструктор QApplication. Проблема заключается в том, что ссылка будет недействительной / висячей, как только вызов конструктора будет завершен. В частности, при вызове exec() позже в методе run объект приложения будет пытаться получить доступ к ссылке, которая завершается с ошибкой и вызывает наблюдаемый сбой.

Короче говоря: как обходной путь, просто укажите аргумент argc в качестве ссылки:

ProgName::ProgName(int &argc, char *argv[], QObject *parent) :
    QObject(parent),
    app(argc, argv)
{
    ui.setupUi(&mainWindow);
}
...