85349

QListWidget causing segmentation fault when clicking and dragging across multiple items

Question:

I have a QListWidget with multiple items each acting like a button responding when clicked on. I have run into a problem where if you click on one item and drag the mouse to anywhere else on the screen apart from the item you clicked on then the program will cause a segmentation fault and crash. Does anyone know how I might fix this?

I have included all the code that I have written below, although this code also relies on proprietary code that I don't think I can post here

<strong>window.cc</strong>

#include "globals.h" #include <QLabel> #include <QBoxLayout> #include <QScrollArea> #include <QListWidget> #include <QListWidgetItem> #include <QPushButton> #include <QMessageBox> #include "windowheader.h" namespace{ class statisticsTab : public QWidget { public: statisticsTab(); private: QGridLayout * layout; QLabel * title; QLabel * userListTitle; QLabel * branchListTitle; UserListWidget * userList; BranchListWidget * branchList; QListWidget * statsPage; }; inline statisticsTab::statisticsTab() : QWidget() { layout = new QGridLayout(); cur_repo = new GITPP::REPO(); title = new QLabel("Repository Statistics"); title->setStyleSheet("QLabel {font-weight: bold;}"); layout->addWidget(title, 0, 0, 1, 2); userListTitle = new QLabel("Contributors"); layout->addWidget(userListTitle, 1, 0, 1, 1); branchListTitle = new QLabel("Branches"); layout->addWidget(branchListTitle, 1, 1, 1, 1); statsPage = new QListWidget(); layout->addWidget(statsPage, 3, 0, 1, 2, Qt::AlignTop); QListWidgetItem * statsPageDefault = new QListWidgetItem(QString("Click on a contributor or branch to get started!"), 0, 0); statsPage->addItem(statsPageDefault); userList = new UserListWidget(statsPage); layout->addWidget(userList, 2, 0, 1, 1); branchList = new BranchListWidget(statsPage); layout->addWidget(branchList, 2, 1, 1, 1); if(cur_repo != nullptr) { GITPP::COMMITS commits = cur_repo->commits(); std::vector <std::string> contributors; for(auto commit : commits) { contributors.push_back(commit.author()); } std::sort(contributors.begin(), contributors.end()); contributors.erase(unique(contributors.begin(), contributors.end()), contributors.end()); for(auto contributor : contributors) { QString contributorName = QString::fromStdString(contributor); QListWidgetItem * contributorNameItem = new QListWidgetItem(contributorName); userList->addItem(contributorNameItem); } GITPP::BRANCHES branches = cur_repo->branches(); for(auto branch : branches) { QListWidgetItem * branchName = new QListWidgetItem(QString::fromStdString(branch.name()), 0, 0); branchList->addItem(branchName); } } else { QListWidgetItem * branchListDefault = new QListWidgetItem(QString("No branches found"), 0, 0); branchList->addItem(branchListDefault); QListWidgetItem * userListDefault = new QListWidgetItem(QString("No users found"), 0, 0); userList->addItem(userListDefault); } setLayout(layout); } INSTALL_TAB(statisticsTab, "Statistics"); }

<strong>windowheader.h</strong>

#ifndef WINDOWHEADER_H #define WINDWOHEADER_H #include <QListWidget> #include <string> #include <limits.h> #include <unistd.h> #include <QPushButton> #include <QFileDialog> #include <QMessageBox> #include "globals.h" class UserListWidget : public QListWidget { Q_OBJECT public: UserListWidget(QListWidget * statsPage); private slots: void updateStatsPage(); private: QListWidget * statsPage; }; inline UserListWidget::UserListWidget(QListWidget * statsPageArg) : QListWidget() { connect(this, SIGNAL(itemSelectionChanged()), this, SLOT(updateStatsPage())); statsPage = statsPageArg; } inline void UserListWidget::updateStatsPage() { GITPP::CONFIG config = cur_repo->config(); GITPP::COMMITS commits = cur_repo->commits(); QString statsTitle = QString("Here are some stats about the user ") + this->currentItem()->text(); QListWidgetItem * statsTitleItem = new QListWidgetItem(statsTitle); statsPage->clear(); statsPage->addItem(statsTitleItem); for(auto thing : config) { QString statsInfo = QString::fromStdString(thing.name()); QListWidgetItem * statsInfoItem = new QListWidgetItem(statsInfo); statsPage->addItem(statsInfoItem); } selectionModel()->clear(); } class BranchListWidget : public QListWidget { Q_OBJECT public: BranchListWidget(QListWidget * statsPage); private slots: void updateStatsPage(); private: QListWidget * statsPage; }; inline BranchListWidget::BranchListWidget(QListWidget * statsPageArg) : QListWidget() { connect(this, SIGNAL(itemSelectionChanged()), this, SLOT(updateStatsPage())); statsPage = statsPageArg; } inline void BranchListWidget::updateStatsPage() { GITPP::CONFIG config = cur_repo->config(); GITPP::COMMITS commits = cur_repo->commits(); QString statsTitle = QString("Here are some stats about the branch ") + this->currentItem()->text(); QListWidgetItem * statsTitleItem = new QListWidgetItem(statsTitle); statsPage->clear(); statsPage->addItem(statsTitleItem); for(auto thing : config) { QString statsInfo = QString::fromStdString(thing.name()); QListWidgetItem * statsInfoItem = new QListWidgetItem(statsInfo); statsPage->addItem(statsInfoItem); } selectionModel()->clear(); } #endif

Valgrind output:

==9475== Invalid read of size 8 ==9475== at 0x1158B5: UserListWidget::updateStatsPage() (in /home/alexis/Desktop/programming/uni_work/comp_2811/cw2/ui_cw3/2811_gui) ==9475== by 0x5F5D5E8: QMetaObject::activate(QObject*, int, int, void**) (in /usr/lib/x86_64-linux-gnu/libQt5Core.so.5.7.1) ==9475== by 0x5F5D5E8: QMetaObject::activate(QObject*, int, int, void**) (in /usr/lib/x86_64-linux-gnu/libQt5Core.so.5.7.1) ==9475== by 0x5EE0BE6: QItemSelectionModel::selectionChanged(QItemSelection const&, QItemSelection const&) (in /usr/lib/x86_64-linux-gnu/libQt5Core.so.5.7.1) ==9475== by 0x5EE544A: QItemSelectionModel::emitSelectionChanged(QItemSelection const&, QItemSelection const&) (in /usr/lib/x86_64-linux-gnu/libQt5Core.so.5.7.1) ==9475== by 0x5EE8F91: QItemSelectionModel::select(QItemSelection const&, QFlags<QItemSelectionModel::SelectionFlag>) (in /usr/lib/x86_64-linux-gnu/libQt5Core.so.5.7.1) ==9475== by 0x54DF9B4: QListView::setSelection(QRect const&, QFlags<QItemSelectionModel::SelectionFlag>) (in /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5.7.1) ==9475== by 0x54C6B3E: QAbstractItemView::mouseMoveEvent(QMouseEvent*) (in /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5.7.1) ==9475== by 0x54E6386: QListView::mouseMoveEvent(QMouseEvent*) (in /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5.7.1) ==9475== by 0x52B8277: QWidget::event(QEvent*) (in /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5.7.1) ==9475== by 0x53A0A0D: QFrame::event(QEvent*) (in /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5.7.1) ==9475== by 0x54C7502: QAbstractItemView::viewportEvent(QEvent*) (in /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5.7.1) ==9475== Address 0x0 is not stack'd, malloc'd or (recently) free'd ==9475== ==9475== ==9475== Process terminating with default action of signal 11 (SIGSEGV) ==9475== Access not within mapped region at address 0x0 ==9475== at 0x1158B5: UserListWidget::updateStatsPage() (in /home/alexis/Desktop/programming/uni_work/comp_2811/cw2/ui_cw3/2811_gui) ==9475== by 0x5F5D5E8: QMetaObject::activate(QObject*, int, int, void**) (in /usr/lib/x86_64-linux-gnu/libQt5Core.so.5.7.1) ==9475== by 0x5F5D5E8: QMetaObject::activate(QObject*, int, int, void**) (in /usr/lib/x86_64-linux-gnu/libQt5Core.so.5.7.1) ==9475== by 0x5EE0BE6: QItemSelectionModel::selectionChanged(QItemSelection const&, QItemSelection const&) (in /usr/lib/x86_64-linux-gnu/libQt5Core.so.5.7.1) ==9475== by 0x5EE544A: QItemSelectionModel::emitSelectionChanged(QItemSelection const&, QItemSelection const&) (in /usr/lib/x86_64-linux-gnu/libQt5Core.so.5.7.1) ==9475== by 0x5EE8F91: QItemSelectionModel::select(QItemSelection const&, QFlags<QItemSelectionModel::SelectionFlag>) (in /usr/lib/x86_64-linux-gnu/libQt5Core.so.5.7.1) ==9475== by 0x54DF9B4: QListView::setSelection(QRect const&, QFlags<QItemSelectionModel::SelectionFlag>) (in /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5.7.1) ==9475== by 0x54C6B3E: QAbstractItemView::mouseMoveEvent(QMouseEvent*) (in /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5.7.1) ==9475== by 0x54E6386: QListView::mouseMoveEvent(QMouseEvent*) (in /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5.7.1) ==9475== by 0x52B8277: QWidget::event(QEvent*) (in /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5.7.1) ==9475== by 0x53A0A0D: QFrame::event(QEvent*) (in /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5.7.1) ==9475== by 0x54C7502: QAbstractItemView::viewportEvent(QEvent*) (in /usr/lib/x86_64-linux-gnu/libQt5Widgets.so.5.7.1)

Answer1:

It appears that the segmentation fault is occurring within the UserListWidget::updateStatsPage() method.

Given the limited information available and that you've said this problem occurs when you drag the mouse off of the item originally clicked, <strong>I suspect</strong> that this->currentItem() is returning a null pointer in the line of code where the method calls this->currentItem()->text(). When you first click on a widget list item, I'm guessing that the UserListWidget::updateStatsPage() method is called with a non-null pointer being returned from this->currentItem(). But then you drag the mouse and if you drag it off of the current item, another itemSelectionChanged() signal is generated. If you've dragged the mouse off of the QListWidget entirely, I imagine the signal would be called at a time when this->currentItem() will return a null pointer indicating that nothing is selected.

Try checking whether this->currentItem() is null and only dereference it if not null.

Recommend

  • Microsoft Owin Security - Claims Constructor Value cannot be null
  • How do I deal with Class 'PHPUnit_Framework_TestCase' not found error?
  • wordpress user roles : contributer can not delete his/here post item
  • How to add users and roles in child team area using plain Java RTC API?
  • Using VBO to draw line string
  • Array of Linked List Homework - Runtime Error
  • KeyError when Key exists
  • R doesn't open with UTF-8
  • Can I use a variable on the same line it is declared in this factory in C++?
  • Run-time Error 424 Object Required UserForm doesnt exist
  • Tips on upgrading CVS to git/hg?
  • Git remove last commits from remote made by someone else
  • Prevent duplicates from adding items from Listbox1 to Listbox2 (VBA excel)
  • How can I see the entire SCM history in my Xcode project?
  • How to integrate a custom GraphicsItem into a QML scene?
  • Boost Fusion: validate adapted struct member ordering at compile time
  • Track files but exclude them from a git bundle
  • How to correctly append dynamic GetUIKit accordions?
  • How to upload specific List image using click on Upload button
  • Can't locate Module/Build.pm in @INC (@INC contains: /usr/local/lib64/perl5
  • Can I use AllJoyn Framework for Wifi Direct in iOS?
  • JavaScript IE rotation transform maths
  • chrome video src change not working
  • How can I replace the server in Web Component Tester
  • Hibernate to update table schema
  • Clear activity stack before launching another activity
  • Who propagate bugfixes across branches (corporate development)?
  • Jenkins: FATAL: Could not initialize class hudson.util.ProcessTree$UnixReflection
  • Jackson Parser: ignore deserializing for type mismatch
  • Record samples being played with OpenAL
  • Change multiple background-images with jQuery
  • How to rebase a series of branches?
  • Jenkins: How To Build multiple projects from a TFS repository?
  • Why ng-show works with ng-repeat but ng-if doesn't? [duplicate]
  • Trying to switch camera back to front but getting exception
  • jquery mobile loadPage not working
  • How do I rollback to a specific git commit
  • Data Validation Drop Down Box Arrow Disappearing
  • How do you join a server to an Active Directory (domain)?