PDA

View Full Version : Access Violation on Signal Emit



khagzan
25th September 2007, 22:22
Hi,

I have been banging my head on this issue for days now. I have a
QFrame which is using a QHBoxLayout. The frame contains one widget, a
custom class inheriting from QTextBrowser. The setup code looks as
follows:

-------------------------------------------------------------------------


int main(int argc, char *argv[]){
int retval = 0;
QApplication application(argc, argv);
QFrame *mainFrame = new QFrame(NULL, 0) ;
QHBoxLayout *frameLayout = new QHBoxLayout() ;
Controller *controller = new Controller(NULL,
MainFrame) ;
TextBrowserWidget *textBrowserWidget = new
TextBrowserWidget(controller, NULL, 0) ;

frameLayout->addWidget(textBrowserWidget) ;
mainFrame->setLayout(frameLayout) ;
controller->ActionSlot(1, QString("Testing")) ;
mainFrame->showMaximized() ;
retval = application.exec() ;
return retval;

}


The notion of the ActionSlot of the controller is to "change the
state" of the QFrame. For this simple example, "changing state" is
simply removing the textBrowserWidget from the frame and replacing it
with a new instance as follows (_mainFrame here is the QFrame from
main above):

-------------------------------------------------------------------------


void Controller::ActionSlot(int action, QVariant parameter){
QHBoxLayout *layout = (QHBoxLayout *)_mainFrame->layout() ;
while(layout->count() > 0){
QLayoutItem *item = layout->itemAt(0) ;
if(item){
QWidget *widget = item->widget() ;
if(widget){
delete widget;
}
}
}
TextBrowserWidget *newBrowser = new TextBrowserWidget(this, NULL,
0) ;
layout->addWidget(newBrowser) ;
fclose(handle) ;
}

-------------------------------------------------------------------------

Now this works well for the first instance of ActionSlot called
explicitly in main above, however I also have the anchorTriggered
signal of QTextBrowser attached to a custom slot in my
TextBrowserWidget class (inheriting from QTextBrowser) so that when a
link in the TextBrowserWidget is clicked, it emits a more
"descriptive" custom signal as follows:

-------------------------------------------------------------------------


.
.
.
QObject::connect(
this,
SIGNAL(anchorClicked(QUrl)),
this,
SLOT(linkClicked(QUrl))
) ;
QObject::connect(
this,
SIGNAL(linkClickedSignal(int, QVariant)),
_controller,
SLOT(ActionSlot(int, QVariant))
) ;
.
.
.
void TextBrowserWidget::linkClicked(QUrl url){
emit linkClickedSignal(1, QString("Testing..."));
}

-------------------------------------------------------------------------

For some reason, as I mentioned the explicit call to ActionSlot from
main() completes successfully. However when I click on one of the
links in the TextBrowserWidget, I receive "0xC0000005: Access
violation writing location 0xfeeefeee." From the stack trace below
this emanates
up from QString's operator "=":

-------------------------------------------------------------------------
[CODE]
QtCored4.dll!q_atomic_decrement(volatile int * ptr=0xfeeefeee) Line
152 + 0x9 bytes C++
QtCored4.dll!QBasicAtomic::deref() Line 76 + 0x10 bytes C++
QtCored4.dll!QString::operator=(const QString & other={...}) Line
1063 + 0x8 bytes C++
QtGuid4.dll!QTextControlPrivate::mouseReleaseEvent (Qt::MouseButton
button=LeftButton, const QPointF & pos={...}) Line 1578 + 0x29 bytes C
++
QtGuid4.dll!QTextControl::processEvent(QEvent * e=0x0012c4d0, const
QMatrix & matrix={...}, QWidget * contextWidget=0x00a077a8) Line 864 C
++
QtGuid4.dll!QTextControl::processEvent(QEvent * e=0x0012c4d0, const
QPointF & coordinateOffset={...}, QWidget * contextWidget=0x00a077a8)
Line 812 C++
QtGuid4.dll!QTextEditPrivate::sendControlEvent(QEv ent * e=0x0012c4d0)
Line 78 + 0x57 bytes C++
QtGuid4.dll!QTextEdit::mouseReleaseEvent(QMouseEve nt * e=0x0012c4d0)
Line 1466 C++
QtGuid4.dll!QTextBrowser::mouseReleaseEvent(QMouse Event *
e=0x0012c4d0) Line 926 C++
QtGuid4.dll!QWidget::event(QEvent * event=0x0012c4d0) Line 6064 C++
QtGuid4.dll!QFrame::event(QEvent * e=0x0012c4d0) Line 641 C++
QtGuid4.dll!QAbstractScrollArea::viewportEvent(QEv ent * e=0x0012c4d0)
Line 903 + 0xc bytes C++
QtGuid4.dll!QAbstractScrollAreaPrivate::viewportEv ent(QEvent *
event=0x0012c4d0) Line 78 + 0x28 bytes C++
QtGuid4.dll!QAbstractScrollAreaFilter::eventFilter (QObject *
o=0x00a077a8, QEvent * e=0x0012c4d0) Line 89 + 0x29 bytes C++
QtGuid4.dll!QApplicationPrivate::notify_helper(QOb ject *
receiver=0x00a077a8, QEvent * e=0x0012c4d0) Line 3533 + 0x1b bytes C+
+
QtGuid4.dll!QApplication::notify(QObject * receiver=0x00a077a8, QEvent
* e=0x0012c4d0) Line 3240 + 0x2f bytes C++
QtCored4.dll!QCoreApplication::notifyInternal(QObj ect *
receiver=0x00a077a8, QEvent * event=0x0012c4d0) Line 516 C++
QtCored4.dll!QCoreApplication::sendSpontaneousEven t(QObject *
receiver=0x00a077a8, QEvent * event=0x0012c4d0) Line 188 + 0x38 bytes
C++
QtGuid4.dll!QETWidget::translateMouseEvent(const tagMSG & msg={...})
Line 2757 + 0x14 bytes C++
QtGuid4.dll!QtWndProc(HWND__ * hwnd=0x004e0572, unsigned int
message=514, unsigned int wParam=0, long lParam=4719072) Line 1390 +
0xc bytes C++
user32.dll!7e418734()
[Frames below may be incorrect and/or missing, no symbols loaded for
user32.dll]
user32.dll!7e418816()
user32.dll!7e4189cd()
user32.dll!7e418a10()
QtCored4.dll!QEventDispatcherWin32::processEvents( QFlags<enum
QEventLoop::ProcessEventsFlag> flags={...}) Line 504 + 0x18 bytes C++
QtGuid4.dll!QGuiEventDispatcherWin32::processEvent s(QFlags<enum
QEventLoop::ProcessEventsFlag> flags={...}) Line 975 + 0x15 bytes C++
QtCored4.dll!QEventLoop::processEvents(QFlags<enum
QEventLoop::ProcessEventsFlag> flags={...}) Line 125 C++
QtCored4.dll!QEventLoop::exec(QFlags<enum
QEventLoop::ProcessEventsFlag> flags={...}) Line 170 + 0x2d bytes C++
QtCored4.dll!QCoreApplication::exec() Line 735 + 0x15 bytes C++
QtGuid4.dll!QApplication::exec() Line 3039 C++
TextBrowserTester.exe!main(int argc=1, char * * argv=0x003e7898) Line
15 + 0x6 bytes C++
TextBrowserTester.exe!WinMain(HINSTANCE__ * instance=0x00400000,
HINSTANCE__ * prevInstance=0x00000000, char * __formal=0x00151f16, int
cmdShow=1) Line 103 + 0x12 bytes C++
TextBrowserTester.exe!__tmainCRTStartup() Line 578 + 0x35 bytes C

TextBrowserTester.exe!WinMainCRTStartup() Line 403 Ckernel32.dll!
7c816fd7()
[/CODE\]
-------------------------------------------------------------------------

My question really is does anyone out there see anything obvious as to
why the access violation is occuring?? Is something being deleted
twice here and I am just not seeing it?? Can I even remove widgets
from a layout this way using delete()?? Is the code I have posted here
just plain wrong?? I have also tried layout->removeItem(), layout-
>removeWidget() to try to remove them from the layout, and surely

layout->count() decrements, but the widget is still visible and
usable. I would rather not use QStackedWidget because I don't want to
leave widgets hanging around wasting resources as there could be a
large number of them if left uncleaned.

Thanks Much

wysota
25th September 2007, 22:31
You can't delete an object that is the sender of the currently processed signal and from what I understand that's what you are trying to do. Use deleteLater() instead of delete.

khagzan
25th September 2007, 22:51
Thank you SOOOOOOO much. deleteLater() works perfectly.