I have a window that's set up with a grid attached to the window, a bunch of stuff in the grid and then a textview on the rightmost column occupying the entire column.
When I add text to the textview, instead of starting to scroll, the window just expands in order to accomodate the text. How can I get it to scroll instead?
Put the text view inside a Gtk::ScrolledWindow and put the scrolled window in the rightmost column of the grid instead.
Related
I am using QCustomPlot to plot a bar graph. There are two such bar graphs horizontally arranged inside a QSplitter (which can be dragged). On dragging the splitter horizontally, the bar graphs resize and scale to the point that the axes labels start to overlap. I have a parent QWidget which contains a QScrollArea which ultimately contains the plot. This widget is added to the QSplitter.
QWidget* topLeftParent = new QWidget;
topLeftParent->setLayout(new QVBoxLayout);
QScrollArea *topLeftScrollArea = new QScrollArea(this);
topLeftScrollArea->setWidget(energyGraph->GetPlot());
topLeftScrollArea->setWidgetResizable(true);
topLeftScrollArea->setFrameShape(QFrame::NoFrame);
topLeftParent->layout()->addWidget(topLeftScrollArea);
m_pTopLeftHorizontalSplitter->setMinimumWidth(500);
m_pTopLeftHorizontalSplitter->addWidget(topLeftParent);
Existing Behaviour:
On dragging the splitter horizontally, the bar graphs expand/shrink horizontally till the axes tick labels overlap and ultimately at a very small value of width, the horizontal scrollbar appears, which is useless. Same is the case for resizing the window as well.
Required Behavior
However, I seek a different behavior. I want the bar graphs to be horizontally scrollable without them resizing on dragging the splitter i.e. dragging the splitter left/right should reveal more/less of the graphs, and not resize them
Queries
How do I specify that the bar graph should have a minimum size and expand from that depending on the number of ticks on x-axis?
How do I stop the plot from automatically expanding/shrinking?
What I have tried so far
I have tried setting minimum size for the plot, but it does not work.
I have also tried specifying the stretch factor for the splitter to 0, but that also has no effect i.e. the behavior is auto resizing bar graphs in both the cases with scrollbar appearing too late.
To achieve the required behavior you can use the QTableWidget widget. You need to:
Create a QTableWidget widget with two columns and and one row.
Set the QScrollArea widget as the parent of the QTableWidget widget.
Hide the horizontal and vertical headers. To do so set horizontalHeaderVisible and verticalHeaderVisible to false.
Add QCustomPlot widgets into the table using the setCellWidget(int row, int column, QWidget * widget) method.
This is how it was solved: I just had to call the setWidgetResizable with false for the scroll area and now I have a permanent scrollbar and the custom plot does not resize while dragging the splitter.
Find if you have this line:
ui->my_plot->setInteractions(QCP::iRangeZoom | QCP::iRangeDrag);
And edit it to whatever you want, for example just range zoom:
ui->my_plot->setInteractions(QCP::iRangeZoom);
I am programming a game and I have a tab widget which takes up the majority of the window. I want to use the extra space in the tab bar for buttons. I have the tab widget in a grid layout. To accomplish this, I use the code below in order to remove and add back the button widgets to the desired areas (the solution to someone else's question).
ui->centralLayout->removeWidget(ui->exitButton);
ui->centralLayout->removeWidget(ui->ResizeButton);
ui->centralLayout->addWidget(ui->ResizeButton,0,4, Qt::AlignTop|Qt::AlignRight);
ui->centralLayout->addWidget(ui->exitButton,0,4, Qt::AlignTop|Qt::AlignRight);
This does not work for me; however, because I would like the second widget-- the resize button-- to be just to the left of the exit button. What is occurring is that it instead overlaps the exit button. I simply need to move it 21 pixels to the left and have no idea how!
I tried putting both buttons in a frame and then removing and adding the frame the way I did the buttons. Unfortunately the same functions I used do not exist for the qt frame object.
Here are some pictures of my window.
https://docs.google.com/document/d/17w5USWQcCtb6OdcRShdcYcRjXTcdVpmdrG5TWLX71y8/edit?usp=sharing
you are using void QGridLayout::addWidget(QWidget * widget, int row, int column, Qt::Alignment alignment = 0) overload.
2-nd and 3-rd parameters are row and column of a grid. And you put 2 widgets in the same cell so they are overlaping each other.
I solved my problem. Earlier when I was trying to add them to a frame and reposition it I could not but using a widget as the container for my buttons let me place them the way I was earlier attempting to individually place the buttons.
I got a multiple selection CListBox with horizontal scroll bar enabled and showed correctly. Problem is, that when I use function
lst.ResetContent() and fill it back, I can't find way to scroll text in the rows back to the same position. I tried to use
lst.SetScrollPos(SB_HORZ, horizScroll, TRUE); , where horizScroll = lst.GetScrollPos(SB_HORZ); This works correctly on scroll bar itself, but
text in the row stays not scrolled (manual scrolling functions OK).
Structure of my program is:
CListBox lst;
int horizScroll;
/*Periodically doing code bellow*/
//Get current scroll position
horizScroll = lst.GetScrollPos(SB_HORZ);
//Reset current content
lst.ResetContent();
//Add item into CListBox (UNICODE in my application)
lst.AddString(L"Some longer text then width of CListBox");
//Calculate horizontal extent and set it through
lst.SetHorizontalExtent(calculatedWidth);
//Try to scroll text (scrolls only scroll bar, not text itself)
lst.SetScrollPos(SB_HORZ, horizScroll, TRUE);
UpdateData(FALSE);
Thanks in advance!
EDIT:
As "rrirower" answered correctly,
lst.PostMessage(WM_HSCROLL, MAKEWPARAM(SB_THUMBPOSITION, 250), 0);
message does the job. Scroll position from horizScroll works perfectly. I suggest posting this message twice, because if you do it only once, text is re-scrolled visually from beginning to the wanted position. When you post it twice, text visually stays at the correct position and scroll bar just quickly comes to the right place.
If I understand you correctly, you're trying to scroll the text in the list box horizontally using the program code. If you use Spy++, you'll see that when you manually scroll, using the mouse, a series of WM_HSCROLL messages is posted to the list box control. You can accomplish the same thing by doing this...
lst.PostMessage(WM_HSCROLL, MAKEWPARAM(SB_THUMBPOSITION, 250), 0);
You need to calculate the position (I used 250 above), but, the above code should move the text and the scroll bar horizontally.
After some reading it seems that Invalidate should do the trick. Since as I understand you have one text line this should be fine, however if the painting itself is complex and requires resources you can use ScrollWindowEx and then InvalidateRect on the rectangle returned by the latter to repaint only the changed area.
How do I place a widget next to a QScrollbar like here seen:
I use a QScrollArea and overwrite the Horizontal-QScrollBar. First I thought, I could use the paintEvent to draw a text like the "100 %" next to the bar. But I can only overwrite the existing painting.
Now I think, the only opportunity would be to implement the hole QScorllBarPrivate from the source code... anyone any idea?
The main idea is to create an overlay obscuring default horizontal scroll bar and displaing your own bottom line instead.
Create a widget representing the bottom line, i.e. a widget with labels displaying some information and a horizontal QScrollBar, all together put in a hbox layout.
Put this widget in the scroll area without adding it to a layout by making QScrollArea direct parent widget of this widget.
Use move() and resize() on the bottom line widget to position it properly on initialization. Also resize and reposition it on scroll area resize (you can use event filters or inheritance to get to resize events).
Make sure that scroll area's horizontalScrollBarPolicy is Qt::ScrollBarAlwaysOn so that scroll area's internal layout always keeps space enough for bottom line widget to fit in.
Also make sure that bottom line widget has the same height as default scroll bar. It should be easy as long as you remove spacing and margins in the hbox layout and labels (or other widgets) don't require more vertical space than a scroll bar.
Use horizontalScrollBar() to get scroll area's internal QScrollBar and syncronize it with your own bar. QScrollBar has rangeChanged() and valueChanged() signals so you can connect to them and update your bar properly. When user changes value of your scroll bar and triggers its valueChanged() signal, you should set the same value for the internal scrollbar. You can protect from infinite recursion in there by using a flag that indicates that this is your own change.
I am using a combobox control to show names stored in a database ( I need to preserve space, that is why I use it instead of a listview, for example ).
My problem is that sometimes text is longer than the combobox so part of it can not be seen.
Is there a way to resize combobox' listbox so it can entirely show text, or at least to enable some kind of horizontal scrolling so the user can scroll to see the entire text?
Looking through combobox documentation, I haven't found any style that can solve my problem. Trying to add WS_HSCROLL as a style in my CreateWindowEx call didn't help either.
Thank you.
You are looking for the CB_SETHORIZONTALEXTENT message.
An application sends the CB_SETHORIZONTALEXTENT message to set the width, in pixels, by which a list box can be scrolled horizontally (the scrollable width). If the width of the list box is smaller than this value, the horizontal scroll bar horizontally scrolls items in the list box. If the width of the list box is equal to or greater than this value, the horizontal scroll bar is hidden or, if the combo box has the CBS_DISABLENOSCROLL style, disabled.
Parameters
wParam
Specifies the scrollable width of the list box, in pixels
lParam
This parameter is not used.