Viewport size adjustment of ScrollView in BlackBerry10 - c++

Hi I need to adjust the viewport of the ScrollView so that it shows up in the middle of the screen. I tried all the properties that I can think of.
Page *page = new Page();
Container *container = new Container();
AbsoluteLayout *absoluteLayout = new AbsoluteLayout();
container->setLayout(absoluteLayout);
for(int y=0;y<1536;y+=256)
{
for(int x=0;x<1536;x+=256)
{
AbsoluteLayoutProperties *imageProperties = AbsoluteLayoutProperties::create().x(x).y(y);
ImageView *imageView = ImageView::create().layoutProperties(imageProperties);
imageView->setImage(Image("assets/tile256.jpg"));
container->add(imageView);
}
}
ScrollView *scrollView = ScrollView::create(container).preferredSize(300,300);
scrollView->setHorizontalAlignment(HorizontalAlignment::Center);
scrollView->setVerticalAlignment(VerticalAlignment::Center);
scrollView->setMaxHeight(300);
scrollView->setMaxWidth(300);
ScrollViewProperties *scrollViewProperties = scrollView->scrollViewProperties();
scrollViewProperties->setScrollMode(ScrollMode::Both);
scrollView->zoomToPoint(300,500,1);
QRectF qRectf = scrollView->viewableArea();
qRectf.setX(300);
qRectf.setY(300);
page->setContent(scrollView);
app->setScene(page);
Here is what I tried.

To dock a control at a specific area, set layout of the container DockLayout and add controls in it. So, even if the control is expanded/contracted it will dock at specified area. Here, add ScrollView in a Container and set that container as content of the page.
Page *page = new Page();
Container *mainContainer = new Container(); //This is the main container of the page
mainContainer->setLayout(new DockLayout()); //To dock scroll view at center of the screen
Container *container = new Container();
...
...
...
mainContainer->add(scrollView);//Add scroll view to the main container
page->setContent(mainContainer);//Set main container as the content
app->setScene(page);

Related

How do I prevent QListView in QGraphicsScene from drawing outside scroll area when scaling with QT_SCALE_FACTOR

When I display a QListWidget or QListView in a QGraphicsScene the text for each item is drawn outside of the widget boundaries if scroll bars are necessary. This only occurs when I use QT_SCALE_FACTOR to scale the application. Is there a way to prevent the list widget/list view items from being displayed outside the scroll area without explicitly setting a width for the items? If I set the width I lose some of the text. I have also tried setting the GraphicsItemFlag QGraphicsItem::ItemClipsToShape. This keeps the overhang restricted to the width of the outer widget but I want to prevent overhang entirely.
QListWidget in QGraphicsScene
QWidget *w = new QWidget();
QVBoxLayout *l = new QVBoxLayout(w);
lw = new QListWidget();
l->addWidget(lw);
QGraphicsProxyWidget *pw = scene()->addWidget(w);
pw->resize(200,300);
for(int i = 0; i < 25; i++) {
QListWidgetItem *litem = new QListWidgetItem("Text text text text text text text");
lw->insertItem(0, litem);
}
Setting the cache mode to QGraphicsItem::DeviceCoordinateCache prevents the listview/listwidget text from displaying outside the boundaries of the widget. The text does become a little blurry but the user can still read it. Thank you harism for your response!
pw->setCacheMode(QGraphicsItem::DeviceCoordinateCache);

Hiding a vertical layout programmatically?

I wanted to know if its possible to hide a vertical layout. I currently have a a horizontal layout with two vertical layouts.I wanted to hide one of the vertical layouts(with all its content) on button click. Any suggestions on how I could do that.
As #jmk said, you need to use a QWidget. I'll just add that it's very easy to turn an existing horizontal or vertical layout into a widget from Qt Designer by right-clicking on it and selecting Morph Into->QWidget:
The layout is entirely preserved, but now you can show/hide the layout box because it's an ordinary widget with that layout.
Instead of inserting vertical layouts directly into your top-level horizontal layout, use container widgets to easily control visibility:
// Create your left and right widgets
QWidget* leftWidget = new QWidget();
QVBoxLayout* leftLayout = new QVBoxLayout(leftWidget);
QWidget* rightWidget = new QWidget();
QVBoxLayout* rightLayout = new QVBoxLayout(rightWidget);
// Populate your vertical layouts here ...
QHBoxLayout* horizontalLayout = new QHBoxLayout(parentWidget);
horizontalLayout->addWidget(leftWidget);
horizontalLayout->addWidget(rightWidget);
Then, you can simply hide or show leftWidget or rightWidget to effectively control the visibility of everything in the vertical layouts that you have, without having to hide/show each individual widget.
My suggestion:
// l is the layout pointer
for (int i = 0; i != l->count(); ++i) {
QWidget* w = qobject_cast<QWidget*>(l->itemAt(i));
if (w != 0) {
w->setVisible(false); // hides the widget
}
else {
// do some recursive things with the layout
}
}
(Hope it works ;))
The widget is basically invisible.

BlackBerry 10 - Adding ImageView to Container

I'm trying to add an ImageView to container, by it doesn't appear on the screen.
Container is created in QML, but I want image to be added in .CPP file.
ApplicationUI.cpp:
ApplicationUI::ApplicationUI(bb::cascades::Application *app)
: QObject(app)
{
QmlDocument *qml = QmlDocument::create("asset:///main.qml").parent(this);
AbstractPane *root = qml->createRootObject<AbstractPane>();
ImageView* imageView1 = new ImageView();
imageView1->setImage(Image("asset:///icon.png"));
Page *page = qml->createRootObject<Page>();
Container *_mRootContainer = page->findChild<Container*>("rootContainer");
_mRootContainer->add( imageView1 );
app->setScene(root);
}
main.xml:
import bb.cascades 1.0
Page {
Container {
objectName: "rootContainer"
Label {
text: "First page"
}
}
}
Thanks in advance ;)
You can create an image container in your .CPP file and then create/add all your images to your container. Eg: using the DockLayout here for images ontop of each other and centered them within parent container.
//Create the images container and center it within parent container
Container *imageContainer = new Container();
imageContainer->setLayout(new DockLayout());
imageContainer->setHorizontalAlignment(HorizontalAlignment::Center);
//Create the image (add the image file into asset folder)
ImageView* imageView1 = ImageView::create("asset:///icon.png");
//Align/center image horizontally and vertically within parent container
imageView1->setHorizontalAlignment(HorizontalAlignment::Center);
imageView1->setVerticalAlignment(VerticalAlignment::Center);
//Add images to image container
imageContainer->add(imageView1);
I recommed to show the image in a WebView
Best of luck

QScrollArea with multiple QWidgets only shows empty box

I am trying to create a widget that would display some information. Each information would be a QWidget that contains multiple QLabel with text (the information). My idea is to put multiple (array of these) into a QScrollArea so that the user can view them scrolling up and down. The following code:
InfoWidget::InfoWidget(QWidget* parent) : QWidget(parent){
widgets = new QVector<MarkerInfoWidget*>();
csv_data = 0;
csv_velocity = 0;
labels = 0;
infoWidgetLayout = new QVBoxLayout(this);
setLayout(infoWidgetLayout);
scrollArea = new QScrollArea(this);
scrollWidgetLayout = new QVBoxLayout(scrollArea);
scrollArea->setLayout(scrollWidgetLayout);
infoWidgetLayout->addWidget(scrollArea);
//Test
QString name = "TEST";
for(int i=0; i<10; i++){
MarkerInfoWidget* markerWidget = new MarkerInfoWidget(name, scrollArea);
scrollWidgetLayout->addWidget(markerWidget);
widgets->append(markerWidget);
}
}
Both MarkerInfoWidget and InfoWidget extends QWidget. What I am getting is simply a box that has very small text:
If I drag it out and re-size it, it display correctly:
What I have noticed is that if I re-size it too small, it does not generate scrolls. What do I need to fix this?
I guess changing:
scrollArea->setLayout(scrollWidgetLayout);
to sth like:
QFrame* frame = new QFrame(scrollArea);
frame->setLayout(scrollWidgetLayout);
scrollArea->setWidget(frame);
As far as i know you have to put widget into QScrollableArea to make it really scrollable. Setting its layout is probably not the thing you want to do.

Minimum size/width of a QPushButton that is created from code

I created 2 rows of push buttons, each row is inside a QHBoxLayout.
I create the buttons in the code:
static const char* buttonText = "23456789TJQKA";
for (int ii = 0; buttonText[ii]; ii++)
{
QPushButton* pushButton = new QPushButton(this);
pushButton->setText(QString(buttonText[ii]));
ui->horizontalLayout_1->addWidget(pushButton);
}
for (int ii = 0; buttonText[ii]; ii++)
{
QPushButton* pushButton = new QPushButton(this);
pushButton->setText(QString(buttonText[ii]));
ui->horizontalLayout_2->addWidget(pushButton);
}
The problem is that they can't shrink (when the user resizes the dialog) beyond that size, even though their text would fit in a much smaller width. If I create the buttons manually in the resource editor instead of in the code, they can have smaller width than that.
This happens because the minimumSizeHint of the QPushButton does not allow the QLayout to resize it :
The default implementation of minimumSizeHint() returns an invalid
size if there is no layout for this widget, and returns the layout's
minimum size otherwise. Most built-in widgets reimplement
minimumSizeHint().
QLayout will never resize a widget to a size smaller than the minimum
size hint unless minimumSize() is set or the size policy is set to
QSizePolicy::Ignore. If minimumSize() is set, the minimum size hint
will be ignored.
The simple solution is to set the minimum width explicitly:
static const char* buttonText = "23456789TJQKA";
for (int ii = 0; buttonText[ii]; ii++)
{
QPushButton* pushButton = new QPushButton(this);
pushButton->setMinimumWidth(5);
pushButton->setText(QString(buttonText[ii]));
ui->horizontalLayout_1->addWidget(pushButton);
}
for (int ii = 0; buttonText[ii]; ii++)
{
QPushButton* pushButton = new QPushButton(this);
pushButton->setMinimumWidth(5);
pushButton->setText(QString(buttonText[ii]));
ui->horizontalLayout_2->addWidget(pushButton);
}
As pnezis wrote, you probably want to override the default minimum size calculated by the button. Here's a way you can do it while avoiding to choose an arbitrary size that might not work when conditions vary (different font or font size, UI style, etc):
QWidget* parent = /* some widget */
auto button = new QPushButton(QLatin1String("X"), parent);
auto textSize = button->fontMetrics().size(Qt::TextShowMnemonic, button->text());
QStyleOptionButton opt;
opt.initFrom(button);
opt.rect.setSize(textSize);
button->setMinimumSize(
button->style()->sizeFromContents(QStyle::CT_PushButton,
&opt,
textSize,
button));
The above was adapted and simplified from QPushButton's own code. You may want to look at the source of QPushButton::sizeHint for all the details.
setMaximumWidth works for me.
sample code is in pyqt, but it should translate directly to C++ without any problems.
from PyQt4 import QtGui
class Window(QtGui.QWidget):
def __init__(self):
super(Window, self).__init__()
layout = QtGui.QHBoxLayout()
texts = [":)",
"&Short",
"&Longer",
"&Different && text",
"More && text",
"Even longer button text", ]
for text in texts:
btn = QtGui.QPushButton(text)
double = text.count('&&')
text = text.replace('&', '') + ('&' * double)
width = btn.fontMetrics().boundingRect(text).width() + 7
btn.setMaximumWidth(width)
layout.addWidget(btn)
self.setLayout(layout)
if __name__ == '__main__':
import sys
app = QtGui.QApplication(sys.argv)
mainWin = Window()
mainWin.show()
sys.exit(app.exec_())