I've got a question about a TextEdit class in Qt.
I'm trying to create a Diff-like program in Qt. So far I'm using the QTextBlock with QTextCursor to color the changed lines on my QPlainTextEdit.
My question is - how can I create that 'spout' that shows the relations between two lines, just like in meld?
As you can see on the screenshot, 10 blue lines in the first file correspond to 4 blue lines in the second file
I think you're going to have to build your own custom widget, derived from QWidget, for that center section, and then handle the painting yourself. The tricky part will likely be the issue of informing the center widget where the colored lines are on each side (which will be related to how they're scrolled) so that it knows where to put the colored sections.
Related
I am new to C++,Qt and Visual Studio and this is my first post on Stack Overflow.
I apologize in advance if this is a repeated question, I tried searching for a similar question but couldn't find one. Let me know if this is a repeated question and I will delete it.
I am trying to create a line plot using QWidget::paintEvent(). The line plot I am drawing is actually a QPainterPath. I want to detect when the mouse hovers over my line plot and so I create a small rectangle where my mouse cursor is and detect when this rectangle intersects with my line plot using bool QPainterPath::intersects() function. The problem is that this function returns true even when my mouse is not exactly over my line plot. In the Image 1 (I am not allowed to embed images yet) my line plot is the thick black curve and the bool QPainterPath::intersects() returns true even when my cursor is over the yellow region. As per the Qt document this is because:
There is an intersection if any of the lines making up the rectangle crosses a part of the path or if any part of the rectangle overlaps with any area enclosed by the path.
There is no way to have a QPainterPath without any enclosed area as Qt only provides two types of fill for QPainterPath: Qt::OddEvenFill or Qt::WindingFill. (To be honest, I find this kind of annoying, since an open path is a series of line segments connected end-to-end, if someone wants to enclose an area they can easily connect the first and last point using either QPainterPath::lineTo() or QPainterPath::moveTo() functions)
Anyway, I decided to get smarter than Qt and drew two extra QPainterPath with pathUp being a few pixels above my line plot and pathDn being a few pixels below my line plot. Image 2 shows these 3 line plots, red one is pathUp, black one is real line plot and green one is pathDn. I thought I coould detect the intersection in the QWidget::mouseMoveEvent() by using the following code:
// cRect: Rectangle at mouse cursor position
if((pathUp.intersects(cRect) && (!pathDn.intersects(cRect))) || ((!pathUp.intersects(cRect)) && pathDn.intersects(cRect)))
{
qDebug() << "Intersects";
}
But this still produces wrong results because now the enclosed area is different, as you can see in Image 3 the green area is an enclosed area of pathDn and red area is the enclosed area of pathUp. The thick black curve is again the line plot that I want to detect my mouse hover on. This enclosed area is not affected by Qt::setFillRule of QPainterPath.
What's even more frustrating is that I tried this technique using QPolygonF instead of QPainterPath on QWidget and the results were exactly the same. I also tried QGraphicsView, there I used QGraphicsPathItem to create my line plot and then used QGraphicsScene::focusItemChanged() signal to detect when I click on my line plot. It again produced the same result of detecting the click when my cursor is over the enclosed area. I do not want to create a custom QGraphicsItem (unless I absolutely have to) just to reimplement it's hoverEnterEvent() and hoverLeaveEvent() method because of the limitations imposed on the boundingRect() of the QGraphicsItem as explained in Qt Docs:
QGraphicsScene expects all items boundingRect() and shape() to remain unchanged unless it is notified. If you want to change an item's geometry in any way, you must first call prepareGeometryChange() to allow QGraphicsScene to update its bookkeeping.
Since I making a plot in real-time the boundingRect() will change quite frequently (> 20 Hz), which will result in an extra computational burden on the software. Is there any way I can solve my problem without creating a custom QGraphicsItem?
P.S. I have been using Stack Overflow for many years whenever I got stuck. I just never made an account here because I never needed to post anything. You guys are the best and I am very happy to be a part of this community!
I was looking for any solution for this problem, but nothing found.
I have something like this:
Those rectangles are my objects. I want to make them selectable - when I click on red rectangle I want to see that this one is selected. If I have those objects saved in QList, can I select exactly that rectangle that I clicked on, and i.e edit it's preferencies?
How to refer to rectangle that I selected?
If you are using a QGraphicsScene and QGraphicsItems/Objects, you can call "QGraphicsItem::setFlags(QGraphicsItem::ItemIsSelectable)" on your QGraphicsItem and then in your QGraphicsItem::paint(..) method check if the option->state is set to QStyle::State_Selected, drawing different properties in this case. If you want a good example of how to do it, i recommend you to read third part of the chapter 8 in the "C++ GUI Programming with Qt, second edition" book.
folks!
I use a listview (Icon mode) to display items which consist of an image and a label.
As you can see in the shots the row height is variable on y depending on the label length. The problem is that I want the complete labels to be drawn, but they are automatically shrinked into two lines:
The strange thing about it is that once you select an item the whole label will be shown:
This is also the case when deselecting the item, but when another item gets selected, only that one will be shown completely.
Is there a way (without drawing the text manually) to avoid truncation in my case?
If some code is needed to answer this question, don't hesitate to ask.
Greetings,
Satara
I'm guessing this was a design choice: make things look less cluttered. E.g. picture your desktop with all labels shown completely... will look messy in my case.
However, you can fix this by drawing the label yourself. Have a look into custom draw which is a service provided by the list control. The thing is that it's usually an all or nothing approach, so this will likely require you to draw everything yourself: border, image, label, etc. The other option is to get hacky: subclass the window and draw the labels again after Windows did in response to several messages (unfortunately Windows does not restrict the painting to WM_PAINT, an optimization that is a left-over from the old days...)
I've been playing around with QtDesigner for some time now, but I can't find a real solution for my desired layout.
Here's what I'm aiming for, kind of an Eclipse RCP-like layout:
Five drag&dropable widgets which can be rearranged and whatnot (so Dockwidgets). Thats what happend in above screenshot, I just pulled five Dockwidgets into the Mainwindow and populated them with Items. But the problem is that Dockwidgets only snap to the edges of the Mainwindow, and leave space to CentralWidget, which you see in the middle. Is there some way to add a containing widget to the center and fill it with DockWidgets?
On a side note: Is it feasable to do something like this in the Designer? I see why this program is useful, as GUIs can be set up and changed extremly fast, but I feel like stripped of any power on the exact look. I'm kinda itching to (attempt to) write the GUI by hand, because I'm feeling so powerless! :-)
P.S.:How can the screenshot be scaled? It seems overly huge
Unfortunately no. As it says in the documentation
Dock windows are secondary windows placed in the dock widget area around the central widget in a QMainWindow.
I subclassed QGraphicsItem and reimplemented paint.
In paint I wrote something like this for labeling the item:
painter->drawText("Test",10,40);
After some time I think It may be useful to handle labeling with seperate item. So I wrote something like this.
QGraphicsTextItem *label = new QGraphicsTextItem("TEST",this);
setPos(10,40);
But two "TEST" drawing do not appear in the same place on screen. I guess difference may be related with item coordinates - scene coordinates. I tried all mapFrom... and mapTo... combinations inside QGraphicsItem interface but no progress. I want to drawings to appear in the same place on screen.
What I miss?
I assume that you are using the same font size and type in both cases. If the difference in position is very small the reason can be the QGraphicTextItem is using some padding for the text it contains. I would try to use QGraphicsSimpleTextItem that is not going to add fancy stuff internally and see if you still have the same problem. The coordinates system is the same one if you use painter or setPost so that is not the problem. If this doesn't help I will suggest to specify the same rect for both to avoid Qt adding it owns separation spaces.