Gunnar Sletta schrieb:
> Tom Schindl wrote:
>> Hi Gunnar,
>>
>> The first thing I found out is that it looks like a problem in QList and
>> Event-Listeners.
>>
>>> Thread 0 Crashed:
>>> 0 <<00000000>> 0x26594a85 0 + 643385989
>>> 1 libqtjambi.jnilib 0x0275367e qtjambi_event_notify(void**) + 80
>>> 2 libQtCore.4.dylib 0x0896fd53
>>> QInternal::activateCallbacks(QInternal::Callback, void**) + 115
>>> 3 libQtCore.4.dylib 0x08a60b11
>>> QCoreApplication::notifyInternal(QObject*, QEvent*) + 49
>>> 4 libQtCore.4.dylib 0x08a63de1
>>> QCoreApplicationPrivate::sendPostedEvents(QObject*, int,
>>> QThreadData*) + 689
>>> 5 libQtGui.4.dylib 0x08d4d68b
>>> QEventDispatcherMac::processEvents(QFlags<QEventLoop::ProcessEventsFlag>)
>>> + 107
>>> 6 libQtCore.4.dylib 0x08a60231
>>> QEventLoop::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) + 65
>>> 7 libQtCore.4.dylib 0x08a602fd
>>> QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) + 157
>>> 8 libQtCore.4.dylib 0x08a64021 QCoreApplication::exec() + 161
>
> I'm afraid not ;)
>
> This only states that the problem occured while an event was being
> delivered, most likely it was a DeleteLater event, caused by a GUI
> object being collected on the GC thread and the deletion being delegated
> back to the GUI thread. We spent a lot of effort ironing out these
> issues back in may, and I was rather confident that we had caught these
> problems, but alas..
>
> Places to look:
> * Do you have any disposeLater() or dispose() in your code?
No dispose() / disposeLater() at all :-(
> * Start looking at the parts of the app where you use temporary GUI
> objects: QFonts, QPixmaps, QRegions, QGraphicsItems, QBrushes, QPens, etc.
>
None of the above is used :-(
Another stacktrace I just got:
> Thread 0 Crashed:
> 0 libcom_trolltech_qt_gui.jnilib 0x0982eedc qtjambi_destructor(void*) +
> 12
> 1 libqtjambi.jnilib 0x027547ef
> QtJambiDestructorEvent::callDestructor() + 57
> 2 libqtjambi.jnilib 0x0275367e qtjambi_event_notify(void**)
> + 80
> 3 libQtCore.4.dylib 0x0896fd53
> QInternal::activateCallbacks(QInternal::Callback, void**) + 115
> 4 libQtCore.4.dylib 0x08a60b11
> QCoreApplication::notifyInternal(QObject*, QEvent*) + 49
> 5 libQtCore.4.dylib 0x08a63de1
> QCoreApplicationPrivate::sendPostedEvents(QObject*, int, QThreadData*) + 689
> 6 libQtGui.4.dylib 0x08d4d68b
> QEventDispatcherMac::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) +
> 107
> 7 libQtCore.4.dylib 0x08a60231
> QEventLoop::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) + 65
> 8 libQtCore.4.dylib 0x08a602fd
> QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) + 157
> 9 libQtCore.4.dylib 0x08a64021 QCoreApplication::exec() +
> 161
The problem occurs with some of my ListWidget-code because when I
comment certain parts the crash is not happening any more.
E.g. when I comment the remove-code or the selection-update-code I don't
get a crash.
The call order is like this:
a) insert x items
b) remove x old items
c) clear the widget
d) set a new selection
I tried to extract the call order but naturally then it doesn't crash.
Tom
/*******************************************************************************
* Copyright (c) 2008, Original authors.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Tom Schindl <[EMAIL PROTECTED]>
*******************************************************************************/
package org.ufacekit.ui.qt.jface;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.ufacekit.ui.viewers.IElementComparer;
import org.ufacekit.ui.viewers.IListViewer;
import org.ufacekit.ui.viewers.LabelConverter;
import com.trolltech.qt.gui.QListWidget;
import com.trolltech.qt.gui.QListWidgetItem;
import com.trolltech.qt.gui.QItemSelectionModel.SelectionFlag;
public class ListViewer<ModelElement, Input> extends Viewer<ModelElement,
Input> implements IListViewer<ModelElement, Input> {
private QListWidget listWidget;
private LabelConverter<ModelElement> labelProvider = new
LabelConverter<ModelElement>();
private boolean blockevent = false;
private class QListWidgetItemImpl extends QListWidgetItem {
private ModelElement data;
}
public ListViewer(QListWidget listWidget) {
this.listWidget = listWidget;
this.listWidget.itemSelectionChanged.connect(this,
"selectionChanged()");
}
private void selectionChanged() {
if( blockevent ) {
return;
}
fireSelectionChangeListener();
}
public LabelConverter<ModelElement> getLabelProvider() {
return labelProvider;
}
public void setLabelProvider(LabelConverter<ModelElement>
labelProvider) {
this.labelProvider = labelProvider;
}
public void add(ModelElement element) {
System.err.println("Adding: " + element);
QListWidgetItem item = createItem(getLabelProvider(), element);
listWidget.addItem(item);
}
public void insert(ModelElement element, int index) {
System.err.println("Inserting: " + element + " => " + index);
QListWidgetItem item = createItem(getLabelProvider(), element);
listWidget.insertItem(index, item);
}
public void remove(ModelElement element) {
System.err.println("Removing: " + element);
QListWidgetItem item = findItem(element);
if( item != null ) {
listWidget.removeItemWidget(item);
}
}
private QListWidgetItem findItem(ModelElement element) {
int size = listWidget.count();
IElementComparer<ModelElement> c = getComparer();
for( int i = 0; i < size; i++ ) {
QListWidgetItemImpl item = (QListWidgetItemImpl)
listWidget.item(i);
if( item.data == element || item.data.equals(element)
|| ( c != null && c.equals(item.data, element) )) {
return item;
}
}
return null;
}
private QListWidgetItemImpl createItem(LabelConverter<ModelElement> cp,
ModelElement element) {
QListWidgetItemImpl item = new QListWidgetItemImpl();
item.data = element;
item.setText(cp.getText(element));
return item;
}
@Override
void doRefreshAll() {
System.err.println("Refresh");
listWidget.clear();
LabelConverter<ModelElement> cp = getLabelProvider();
Collection<ModelElement> elements =
getFilteredAndSortedElements();
int i = 0;
for( ModelElement element: elements ) {
listWidget.insertItem(i++,createItem(cp, element));
}
}
@Override
List<ModelElement> doGetSelectedElements() {
List<QListWidgetItem> items = listWidget.selectedItems();
List<ModelElement> rv = new
ArrayList<ModelElement>(items.size());
for( QListWidgetItem item: items ) {
rv.add(((QListWidgetItemImpl)item).data);
}
return rv;
}
@Override
void doSetSelectedElements(List<ModelElement> elements) {
blockevent = true;
System.err.println("SELECTION: " + elements);
listWidget.clearSelection();
for( ModelElement element: elements ) {
QListWidgetItem item = findItem(element);
if( item != null ) {
listWidget.setCurrentItem(item,SelectionFlag.Select);
}
}
System.err.println("SELECTION DONE: " + elements);
blockevent = false;
// fireSelectionChangeListener();
}
}package org.ufacekit.ui.qt.jface.examples;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import org.ufacekit.ui.viewers.IElementComparer;
import org.ufacekit.ui.viewers.LabelConverter;
import com.trolltech.qt.gui.QApplication;
import com.trolltech.qt.gui.QDialog;
import com.trolltech.qt.gui.QGridLayout;
import com.trolltech.qt.gui.QListWidget;
import com.trolltech.qt.gui.QListWidgetItem;
import com.trolltech.qt.gui.QPushButton;
import com.trolltech.qt.gui.QItemSelectionModel.SelectionFlag;
public class QTListBug extends QDialog {
private QListWidget widget;
private static ArrayList<String> VALUES_1 = new ArrayList<String>();
{
VALUES_1.add("Tyrol");
VALUES_1.add("Vorarlberg");
VALUES_1.add("Salzburg");
VALUES_1.add("Upper Austria");
VALUES_1.add("Carinthia");
VALUES_1.add("Styria");
VALUES_1.add("Lower Austria");
VALUES_1.add("Vienna");
VALUES_1.add("Burgenland");
}
private static ArrayList<String> VALUES_2 = new ArrayList<String>();
{
VALUES_2.add("London");
VALUES_2.add("West Yorkshire");
VALUES_2.add("South Yorkshire");
VALUES_2.add("Upper Austria");
VALUES_2.add("North Yorkshire");
VALUES_2.add("Somerset");
}
private static boolean flag = true;
private class QListWidgetItemImpl extends QListWidgetItem {
private Object data;
}
public QTListBug() {
QGridLayout layout = new QGridLayout();
widget = new QListWidget();
widget.itemSelectionChanged.connect(this, "modify2()");
QListWidget selectionWidget = new QListWidget();
selectionWidget.itemSelectionChanged.connect(this, "modify()");
selectionWidget.addItems(Arrays.asList("A","B","C","D"));
doRefreshAll(VALUES_1);
doSetSelectedElements(Collections.singletonList(VALUES_1.get(0)));
layout.addWidget(widget);
layout.addWidget(selectionWidget);
setLayout(layout);
}
public void modify2() {
System.err.println("SELECTION CHANGED FIRED");
}
public void modify() {
ArrayList<String> insert;
ArrayList<String> remove;
if( flag ) {
insert = VALUES_2;
remove = VALUES_1;
} else {
insert = VALUES_1;
remove = VALUES_2;
}
int i = 0;
for( String s: insert ) {
insert(s,i++);
}
for( String s: remove ) {
remove(s);
}
doRefreshAll(insert);
doSetSelectedElements(Collections.singletonList(insert.get(0)));
flag = !flag;
}
private void doRefreshAll(ArrayList<String> elements) {
System.err.println("Refresh");
widget.clear();
int i = 0;
for( String element: elements ) {
widget.insertItem(i++,createItem(element));
}
}
private QListWidgetItem findItem(String element) {
int size = widget.count();
for( int i = 0; i < size; i++ ) {
QListWidgetItemImpl item = (QListWidgetItemImpl)
widget.item(i);
if( item.data == element || item.data.equals(element) )
{
return item;
}
}
return null;
}
private QListWidgetItemImpl createItem(String element) {
QListWidgetItemImpl item = new QListWidgetItemImpl();
item.data = element;
item.setText(element);
return item;
}
public void add(String element) {
System.err.println("Adding: " + element);
QListWidgetItem item = createItem(element);
widget.addItem(item);
}
public void insert(String element, int index) {
System.err.println("Inserting: " + element);
QListWidgetItem item = createItem(element);
widget.insertItem(index, item);
}
public void remove(String element) {
System.err.println("Removing: " + element);
QListWidgetItem item = findItem(element);
if( item != null ) {
widget.removeItemWidget(item);
}
}
/**
* @param args
*/
public static void main(final String[] args) {
QApplication.initialize(args);
new QTListBug().show();
QApplication.exec();
}
void doSetSelectedElements(List<String> elements) {
System.err.println("SELECTION: " + elements);
widget.clearSelection();
for( String element: elements ) {
QListWidgetItem item = findItem(element);
if( item != null ) {
widget.setCurrentItem(item,SelectionFlag.Select);
}
}
System.err.println("SELECTION DONE: " + elements);
// fireSelectionChangeListener();
}
}
_______________________________________________
Qt-jambi-interest mailing list
[email protected]
http://lists.trolltech.com/mailman/listinfo/qt-jambi-interest