How to analyse a "Binding loop" - qt

I have a Qt/QML application with a C++ model and a QML visualisation.
At run-time (start-up), I get a warning
QML Item: Binding loop detected for property "xyz"
I see no obvious loop in my QML.
Can I enable more debugging to understand where this loop comes from? Other suggestions?

I usually do this by placing a breakpoint in the Qt code that prints the warning. For that, you need to have a Qt with debug symbols.
Searching for "Binding loop detected" in the Qt sources gives me QQmlAbstractBinding::printBindingLoopError(). Placing a breakpoint there will usually lead to a backtrace that gives a clear picture of the situation.
Update: David Edmundson has developed a little tool that displays a QML-only backtrace on binding loops, see his blog here. Under the hood is does exactly what is described here, only that it is nicely automated and wrapped in a Python script.
Example:
Rectangle {
id: parent
width: child.width + 1
height: child.height + 1
Rectangle {
id: child
anchors.fill: parent
}
}
Backtrace:
1 QQmlAbstractBinding::printBindingLoopError qqmlabstractbinding.cpp 178 0x7ffff6eb36da
2 QQmlBinding::update qqmlbinding.cpp 221 0x7ffff6eb9abe
3 QQmlBinding::update qqmlbinding_p.h 97 0x7ffff6eba354
4 QQmlBinding::expressionChanged qqmlbinding.cpp 260 0x7ffff6eb9e68
5 QQmlJavaScriptExpressionGuard_callback qqmljavascriptexpression.cpp 361 0x7ffff6eb223e
6 QQmlNotifier::emitNotify qqmlnotifier.cpp 94 0x7ffff6e9087a
7 QQmlData::signalEmitted qqmlengine.cpp 763 0x7ffff6e19a45
8 QMetaObject::activate qobject.cpp 3599 0x7ffff683655e
9 QMetaObject::activate qobject.cpp 3578 0x7ffff6836364
10 QQuickItem::widthChanged moc_qquickitem.cpp 1104 0x7ffff7a7ba49
11 QQuickItem::geometryChanged qquickitem.cpp 3533 0x7ffff7a6e9cd
12 QQuickItem::setSize qquickitem.cpp 6389 0x7ffff7a75f35
13 QQuickAnchorsPrivate::setItemSize qquickanchors.cpp 400 0x7ffff7a60d94
14 QQuickAnchorsPrivate::fillChanged qquickanchors.cpp 177 0x7ffff7a5fe0e
15 QQuickAnchorsPrivate::itemGeometryChanged qquickanchors.cpp 441 0x7ffff7a6106f
16 QQuickItem::geometryChanged qquickitem.cpp 3523 0x7ffff7a6e96c
17 QQuickItem::setWidth qquickitem.cpp 6091 0x7ffff7a74c1d
18 QQuickItem::qt_static_metacall moc_qquickitem.cpp 874 0x7ffff7a7b0dc
19 QQuickItem::qt_metacall moc_qquickitem.cpp 946 0x7ffff7a7b4d8
20 QQuickRectangle::qt_metacall moc_qquickrectangle_p.cpp 610 0x7ffff7c189c2
21 QMetaObject::metacall qmetaobject.cpp 296 0x7ffff680118b
22 QQmlPropertyPrivate::writeBinding qqmlproperty.cpp 1512 0x7ffff6e33ec3
23 QQmlBinding::update qqmlbinding.cpp 199 0x7ffff6eb992a
24 QQmlBinding::update qqmlbinding_p.h 97 0x7ffff6eba354
25 QQmlBinding::expressionChanged qqmlbinding.cpp 260 0x7ffff6eb9e68
26 QQmlJavaScriptExpressionGuard_callback qqmljavascriptexpression.cpp 361 0x7ffff6eb223e
27 QQmlNotifier::emitNotify qqmlnotifier.cpp 94 0x7ffff6e9087a
28 QQmlData::signalEmitted qqmlengine.cpp 763 0x7ffff6e19a45
29 QMetaObject::activate qobject.cpp 3599 0x7ffff683655e
30 QMetaObject::activate qobject.cpp 3578 0x7ffff6836364
31 QQuickItem::widthChanged moc_qquickitem.cpp 1104 0x7ffff7a7ba49
32 QQuickItem::geometryChanged qquickitem.cpp 3533 0x7ffff7a6e9cd
33 QQuickItem::setSize qquickitem.cpp 6389 0x7ffff7a75f35
34 QQuickAnchorsPrivate::setItemSize qquickanchors.cpp 400 0x7ffff7a60d94
35 QQuickAnchorsPrivate::fillChanged qquickanchors.cpp 177 0x7ffff7a5fe0e
36 QQuickAnchorsPrivate::update qquickanchors.cpp 431 0x7ffff7a60fc6
37 QQuickAnchorsPrivate::updateOnComplete qquickanchors.cpp 425 0x7ffff7a60f93
38 QQuickItem::componentComplete qquickitem.cpp 4593 0x7ffff7a70944
39 QQmlObjectCreator::finalize qqmlobjectcreator.cpp 1207 0x7ffff6ecab66
40 QQmlComponentPrivate::complete qqmlcomponent.cpp 928 0x7ffff6e38609
41 QQmlComponentPrivate::completeCreate qqmlcomponent.cpp 964 0x7ffff6e386ee
42 QQmlComponent::completeCreate qqmlcomponent.cpp 957 0x7ffff6e386a0
43 QQmlComponent::create qqmlcomponent.cpp 791 0x7ffff6e37edd
44 QQuickView::continueExecute qquickview.cpp 476 0x7ffff7b720d4
45 QQuickViewPrivate::execute qquickview.cpp 124 0x7ffff7b7101f
46 QQuickView::setSource qquickview.cpp 253 0x7ffff7b71426
47 main main.cpp 24 0x4033e4
In the backtrace, one can see that the anchors.fill anchor for the child item is calculated when loading the file (frame 35, 36). That causes the child item's width to change (frame 31), which causes a binding update (frame 25) for a binding on the "width" property (frame 17) on the parent item. That in turn forces a recalculation of the child anchors (frame 14), which changes the child's width (frame 10), which updates a binding (frame 4). That is the same binding that was already being updated in frame 25, hence a binding loop exists. One can see that the this pointer in frame 25 and frame 4 are the same, i.e. the same binding is updated recursively.

Thanks much for the receipt however it did not help me. In case somebody will need it, adding another possible solution. I was getting binding loops in ListView trying to set all items width and list width to item max value:
ListView {
implicitWidth: contentItem.childrenRect.width
delegate: listItem
}
Item {
id: listItem
width: Math.max(internalWidth, listView.implicitWidth)
}
Binding loop error appeared on items count update but not every time - only on some batch binding updates, while the is no actual binding loop. Was able to solve the issue by moving binding expression to Binding QML Type and adding delayed property to it:
Item { // Item causing binding loop
Binding on item_property_causing_loop {
value: <binding_expression>
when: <when_expression> // Optional however could also help
delayed: true // Prevent intermediary values from being assigned
}
}
So in my case it is:
Item { // Item causing binding loop
id: listItem
Binding on width {
value: Math.max(internalWidth, listView.implicitWidth)
when: index >= 0 // Optional however could also help
delayed: true // Prevent intermediary values from being assigned
}
}

Related

Decode Epson print (ESC-i) command decoding/encoding

I'm trying to understand the algorithm used for compression value = 1 with the Epson ESCP2 print command, "ESC-i". I have a hex dump of a raw print file which looks, in part, like the hexdump below (note little-endian format issues).
000006a 1b ( U 05 00 08 08 08 40 0b
units; (page1=08), (vt1=08), (hz1=08), (base2=40 0b=0xb40=2880)
...
00000c0 691b 0112 6802 0101 de00
esc i 12 01 02 68 01 01 00
print color1, compress1, bits1, bytes2, lines2, data...
color1 = 0x12 = 18 = light cyan
compress1 = 1
bits1 (bits/pixel) = 0x2 = 2
bytes2 is ??? = 0x0168 = 360
lines2 is # lines to print = 0x0001 = 1
00000c9 de 1200 9a05 6959
00000d0 5999 a565 5999 6566 5996 9695 655a fd56
00000e0 1f66 9a59 6656 6566 5996 9665 9659 6666
00000f0 6559 9999 9565 6695 9965 a665 6666 6969
0000100 5566 95fe 9919 6596 5996 5696 9666 665a
0000110 5956 6669 0456 1044 0041 4110 0040 8140
0000120 9000 0d00
1b0c 1b40 5228 0008 5200 4d45
FF esc # esc ( R 00 REMOTE1
The difficulty I'm having is how to decode the data, starting at 00000c9, given 2 bits/pixel and the count of 360. It's my understanding this is some form of tiff or rle encoding, but I can't decode it in a way that makes sense. The output was produced by gutenprint plugin for GIMP.
Any help would be much appreciated.
The byte count is not a count of the bytes in the input stream; it is a count of the bytes in the input stream as expanded to an uncompressed form. So when expanded, there should be a total of 360 bytes. The input bytes are interpreted as either a count of bytes to follow, if positive, in which case the count is the byte value +1; and if negative the count is a count of the number of times the immediately following byte should be expanded, again, +1. The 0D at the end is a terminating carriage return for the line as a whole.
The input stream is only considered as a string of whole bytes, despite the fact that the individual pixel/nozzle controls are only 2 bits each. So it is not really possible to use a repeat count for something like a 3-nozzle sequence; a repeat count must always specify a full byte 4-nozzle combination.
The above example then specifies:
0xde00 => repeat 0x00 35 times
0x12 => use the next 19 bytes as is
0xfd66 => repeat 0x66 4 times
0x1f => use the next 32 bytes as is
etc.

How to speed up a while-loop in R (perhaps using dopar)?

I'm trying to process a huge text file containing dozens millions lines of text. The text file contains the results of a convnet analysis of several millions of images and looks like this:
CUDNN_HALF=1
net.optimized_memory = 0
mini_batch = 1, batch = 8, time_steps = 1, train = 0
nms_kind: greedynms (1), beta = 0.600000
nms_kind: greedynms (1), beta = 0.600000
nms_kind: greedynms (1), beta = 0.600000
seen 64, trained: 447 K-images (6 Kilo-batches_64)
Enter Image Path: data/obj1/H001683-19-1-5-OCT2 [x=13390,y=52118,w=256,h=256].png: Predicted in 19.894000 milli-seconds.
tumor: 99% (left_x: 2 top_y: 160 width: 67 height: 34)
bcell: 98% (left_x: 6 top_y: 54 width: 32 height: 22)
bcell: 80% (left_x: 51 top_y: 0 width: 30 height: 16)
bcell: 98% (left_x: 52 top_y: 198 width: 28 height: 26)
bcell: 98% (left_x: 150 top_y: 216 width: 35 height: 23)
bcell: 56% (left_x: 150 top_y: 78 width: 45 height: 30)
bcell: 91% (left_x: 187 top_y: 132 width: 31 height: 26)
bcell: 96% (left_x: 219 top_y: 185 width: 20 height: 26)
bcell: 37% (left_x: 222 top_y: -0 width: 24 height: 4)
bcell: 98% (left_x: 241 top_y: 208 width: 15 height: 21)
bcell: 64% (left_x: 248 top_y: 35 width: 8 height: 35)
[... a lot of similar lines...]
Enter Image Path: data/obj1/H001683-19-1-5-OCT2 [x=13390,y=52530,w=256,h=256].png: Predicted in 19.195000 milli-seconds.
bcell: 97% (left_x: 45 top_y: 180 width: 29 height: 24)
bcell: 58% (left_x: 59 top_y: 1 width: 35 height: 22)
tumor: 98% (left_x: 105 top_y: 143 width: 99 height: 44)
tumor: 97% (left_x: 113 top_y: 50 width: 57 height: 40)
bcell: 96% (left_x: 191 top_y: 194 width: 29 height: 27)
bcell: 99% (left_x: 201 top_y: 129 width: 34 height: 22)
Enter Image Path:
Each image is mentioned by the image file name after "Enter Image Path" followed by a list of objects which were identified. I do not know a priori, how many objects (here tumor an bcell) are in each image. Sometimes where are no objects at all, sometimes where are hundreds.
I first tried to read the whole file using
test11<-readLines("result.txt")
picsna<-grep(test11,pattern="Enter Image") # line numbers with the image file name
lle<-length(picsna) # length for the subsequent script
and then to go ahead with my script but it proved to take hours to read the file so I came with the Idea to read the file line by line and execute my code "on the fly" using a while-loop:
require(LaF)
n=1
lle<-0 # number of images (to be used in a subsequent code)
picsna<-c() # vector with the line numbers of each image entry
# read the result-file initially (first bunch of lines do not contain image entries
test11<-get_lines(file="result.txt", line_numbers=n)
# as long as the line exists read the next line and do following:
while(is.na(test11)==FALSE){
test11<-get_lines(file="result.txt", line_numbers=n+1)
# I wanted to know how far my reading progressed but had a feeling, print slowed down the loop
#print(n)
# I found here this solution for printing progress periodically
if(n %% 10000==0) {
cat(paste0("iteration: ", n, "\n"))
}
# look for image entry and save the line number (not the iteration number)
if(grepl(test11,pattern="Enter Image")==TRUE){
picsna<-c(picsna,n+1)
lle<-lle+1} # increase the number of images
n<-n+1
}
# the last line of the file is always incomplete but has to be added to the vector to calculate the number of objects (in a following script not shown here) if the previous image had any.
if(is.na(test11)==TRUE){
picsna<-c(picsna,n)
print("The End")
lle<-lle+1
}
I measured the elapsed time for the first and the second script on a small result file containing about 200 lines. The second script was even a little bit slower (0.04 vs 0.01), which confused me.
I thought about rewriting it in a foreach-%dopar%-loop but could not realize how to implement it with the readLines-function or with my while-loop. My problem is, that I do not know apriori how many lines the file contains. I would really appreciate if somebody could help me to parallelize my script!
Thank you #Bas! I tested your suggestion on a Linux machine: for a file with ~239 million lines it took less than 1 min. By adding >lines.txt I could save the results. Interestingly, my first readLines R script needed "only" 29 min, which was surprisingly fast compared with my first experience (so I might have had some problem with my Windows computer at work which was not related to R).

How to get the last elements of the values of selected keys of a dictionary in DolphinDB?

dt=dict(STRING,ANY)
dt[`AAPL]=10 11 12
dt[`AMZN]=61 62 63
dt[`NFLX]=34 35 36 37;
For this dictionary in DolphinDB, how can I take the last element of the value for AAPL and NFLX to get the vector [12,37]?
Try this:
def f(d, symbols){
return each(x->d[x].tail(), symbols)
}
f(dt, `AAPL`NFLX);

R: Combine fragments below certain length

I have a bed file containing restriction fragments of the mouse genome. Each fragment has a different length/width, like this:
chr start end width
1 chr1 0 3000534 3000534
2 chr1 3000535 3000799 264
3 chr1 3000800 3001209 409
4 chr1 3001210 3001496 286
5 chr1 3001497 3002121 624
Is it possible to combine shorter fragments ( < 500bp) with adjacent fragments using R (see example below) and if yes how?
chr start end width
1 chr1 0 3000534 3000534
2 chr1 3000535 3001209 673
3 chr1 3001210 3002121 910
Note, I don't want to filter out fragments under a certain length, so sub setting the data is not an option.
I hope my question is not too confusing…
Here is a first solution, that supposes that chr stays the same and that filters out the last fragment if it is < 500 (the result is the dataframe you put in your example) :
mydata<-data.frame(chr=rep("chr1",6),start=c(0,3000535,3000800,3001210,3001497,3002122),end=c(3000534,3000799,3001209,3001496,3002121,3002134),width=c(3000534,264,409,286,624,12),stringsAsFactors=F)
i<-1
while(i<nrow(mydata)){
if(mydata$width[i]>=500) {
i<-i+1
} else {
mydata$end[i]<-mydata$end[i+1]
mydata$width[i]<-sum(mydata$width[i:(i+1)])
mydata<-mydata[-(i+1),]
}
}
if(mydata$width[i]<500) mydata<-mydata[-i,]

Awk script for substracting from the above field

Hi I have my input file with one field:
30
58
266
274
296
322
331
I need the output to be the difference of 2nd and 1st rows(58-30=28) and 3rd and 2nd rows(266-58=208) and so on.
my output should look like below:
30 30
58 28
266 208
274 8
any help please?
data=`cat file | xargs`
echo $data | awk '{a=0; for(i=1; i<=NF;i++) { print $i, $i-a; a=$i}}'
30 30
58 28
266 208
274 8
296 22
322 26
331 9
Update upon comment Without cat/xargs:
awk '{printf "%d %d\n", $1, $1-a; a=$1;}' file
You don't actually need the for loop from Khachick's answer as Awk will go through all the rows anyway. Simpler is:
cat file | awk '{ BEGIN { a=0 }; { print $1, $1-a; a=$1 }'
However it is also possible to skip the first row that you don't really want by initialising a variable in the BEGIN block and not doing the print if the variable is so initialised before changing its value. Sort of like:
BEGIN { started=0 }; { if(0 == started) { started = 1 } else { print $1, $1-a } }

Resources