I can get the line of the cursor by using QTextEdit.textCursor().blockNumber(), but when one line wrap into multi-lines, it can not return the actual line number.
How can I do that?
I wasn't sure it will work, so I wrote a quick test application (Qt 5.0.1) and this works, here is piece of it:
void MainWindow::on_plainTextEdit_cursorPositionChanged()
{
QPlainTextEdit *edit = qobject_cast<QPlainTextEdit *>(sender());
Q_ASSERT(edit);
QTextCursor cursor = edit->textCursor();
cursor.movePosition(QTextCursor::StartOfLine);
int lines = 1;
while(cursor.positionInBlock()>0) {
cursor.movePosition(QTextCursor::Up);
lines++;
}
QTextBlock block = cursor.block().previous();
while(block.isValid()) {
lines += block.lineCount();
block = block.previous();
}
ui->label->setText(QString::number(lines));
}
Here is a similar solution in Python. It fixes the problem I noted in comment on the earlier one above. This is a method in a subclass of QTextEdit:
def getLineAtPosition(self, pos):
cursor = self.textCursor()
cursor.setPosition(pos)
cursor.movePosition(QTextCursor.StartOfLine)
lines = 0
lines_text = cursor.block().text().splitlines()
lines_pos = 0
for line_text in lines_text:
lines_pos += len(line_text) + 1
if lines_pos > cursor.position() - cursor.block().position():
break
lines += 1
block = cursor.block().previous()
while block.isValid():
lines += block.lineCount()
block = block.previous()
return lines
QTextCursor has a lot of useful methods, like:
int QTextCursor::position () const
Returns the absolute position of the cursor within the document. The cursor is positioned between characters.
and
int QTextCursor::positionInBlock () const
Returns the relative position of the cursor within the block. The cursor is positioned between characters.
This is equivalent to position() - block().position().
Related
I am using Kotlin with JavaFX. In a TextArea which is programmatically appended, I want the scrollbar to always jump to the bottom when text is added.
To test this, I wrote this code:
taConsole.text = "Running " + pythonScriptPath
// retrieve output from python script
val bfr = BufferedReader(InputStreamReader(p.inputStream))
val lines = bfr.readLines()
for (i in 1..10) {
for (line in lines) {
taConsole.appendText("\n" + line)
}
}
Sadly, I cant get it to scroll to bottom. I already tried:
ta.selectEnd();
ta.deselect();
dataPane.setScrollTop(Double.MAX_VALUE);
and
val caret = taConsole.selectPositionCaret(taConsole.length)
I inserted them after the:
appendText("\n" + line)
I'm using the angular-ui ui-scroll and it's great when I scroll down, keeps adding items as expected. However when I scroll up, it stops at the top of the last batch that I loaded. For example if I have 100 items and my buffer size is 10, and I've scrolled down so that items 61-70 are showing, when I scroll back up I want to see items 51-60. However I can't scroll up past item 61. I don't know what I'm doing wrong.
Here's the html:
<div row="row" ui-scroll="row in transactionSource" buffer-size="10" >{{row.data}}</sq-transaction>
Here's the script:
$scope.transactionSource = {
get: function (index, count, callback) {
if (index < 0) {
callback([])
}
else {
var buffer = 10;
var end = ctrl.nextIndex + buffer;
if (end > ctrl.transactions.length) end = ctrl.transactions.length;
var items = ctrl.transactions.slice(ctrl.nextIndex, end);
ctrl.nextIndex = end;
callback(items);
}
}
};
If it's related, when I console.log the index and count values received, after the first load of 10 I get an index of -9 (in which case I return an empty array - if I don't do this, the entire array gets loaded). When I scroll up, I don't get a console.log message at all so it's like the 'get' only gets called when scrolling down.
Thanks in advance for any and all help.
Your datasource looks wrong. Items retrieving (slicing in your case) should be based on index and count parameters that you have from the datasource.get method arguments. I'd like to post an example of datasource implementation where the result items array is limited from 0 to 100 and should be sliced from some external data array:
get: function(index, count, success) {
var result = [];
var start = Math.max(0, index);
var end = Math.min(index + count - 1, 100);
if (start <= end) {
result = externalDataArray.slice(start, end + 1);
}
success(result);
};
Hope it helps!
So here is my problem. I want to loop through every point of a line chart in HighCharts using Selenium. I figured a way to start from path:nth-of-type(1) to path:last-of-type. However, it goes from right to left and I would love to have it going from left to right (I'm peaky I know).
Thus, if I could find a way to start from last-of-type to nth-of-type(1), I would be very pleased. However, I don't know how to get the equivalent nth-of-type(position) of last-of-type in order to decrease it by 1 every time I loop through it.
Here is the code I have so far (the right to left one):
public static boolean isLastPoint(int series,WebDriver driver){
if(series > 1){
WebElement last = driver.findElement(By.cssSelector("g.highcharts-series-group > g:nth-of-type(2) > path:last-of-type"));
WebElement current = driver.findElement(By.cssSelector("g.highcharts-series-group > g:nth-of-type(2) > path:nth-of-type(" + (series) + ")"));
return last.equals(current);
}
else return false;
}
public static void overview(WebDriver driver, boolean active) {
if(active){
wait(driver,By.id("highcharts-0"));
WebElement chart0 = driver.findElement(By.id("highcharts-0"));
LineChart lc0 = new LineChart(driver,chart0);
int series = 1;
while(!isLastPoint(series-1,driver)){
lc0.hoverOverLineChart1(series, "");
series++;
}
}else return;
}
You can use findElements for this:
int count = driver.findElements(By.cssSelector("g.highcharts-series-group > g:nth-of-type(2) > path:last-of-type")).size();
Then use the count to iterate backwards.
I have simple Qt GUI application which uses QtWebkit. I am loading complex page with a lot of nested IFRAME-tags. And I want to traverse complete DOM tree (like Chrome browser does in debug-panel) including content of iframes.
My code is:
QWebElement doc = ui->webView->page()->mainFrame()->documentElement();
QWebElement iframe = doc.findFirst("iframe[id=someid]");
QWebFrame *webFrame = ....? // how to get the QWebFrame for an iframe/frame QWebElement?
Note:
I can traverse over all frames (including nested):
void MainWindow::renderFramesTree(QWebFrame *frame, int indent)
{
QString s;
s.fill(' ', indent * 4);
ui->textLog->appendPlainText(s + " " + frame->frameName());
foreach (QWebFrame *child, frame->childFrames())
renderFramesTree(child, indent + 1);
}
But my question is not about that. I need to get corresponding QWebFrame* of iframe-QWebElement.
Thanx!
Each QWebFrame has QList<QWebFrame *> QWebFrame::childFrames () const method. Each frame has also QString QWebFrame::frameName () const. Combining both may let you find what you need.
QWebFrame * frameImLookingFor = NULL;
foreach(QWebFrame * frame, ui->webView->page()->mainFrame()->childFrames())
{
if (frame->frameName() == QLatin1String("appFrame"))
{
frameImLookingFor = frame;
break;
}
}
if (frameImLookingFor)
{
// do what you need
}
run selector on current frame
if it returns something that's good we found that our webframe is on the current frame, lets call this element X :
now get all frame elements using selector "iframe,frame" from current page
loop trough all those elements and try to match them with X frame
this way you'll be able to find exact INDEX of the X frame in document
finally you are now able to focus on child frame with that INDEX
else this means that selector is not found in this frame
loop trough all child frames and repeat the whole process for each child frame
I have a text area control on a form that is supposed to accept 5 digit US zip codes. I have assigned the control a keyUp event that checks the number of characters entered until it reaches 5 then forces a new line.
public function forceNewLine(event:KeyboardEvent):void
{
var maxLineChars:int = 5;
var currentLine:int = 1;
var numChars:int;
numChars = (txtList.text.length);
currentLine = Math.round(txtList.text.length / 6);
if (numChars == (maxLineChars * currentLine))
{
txtList.text = txtList.text + "\n";
txtList.setCursorPosition()
//This is not a function I have defined but I think I need too..
}
}
<s:TextArea id="txtList" keyUp="forceNewLine(event)"/>
It works fine except that when the new line is inserted, the cursor moves to the beginning of the textarea. I want it to go to the end.
Try using the selectRange function of the spark textArea.
txtList.selectRange(txtList.text.length, txtList.text.length)