How to set Susy gutter width to be more than 1 column - susy

I'm using with-layout to temporarily set defaults for my page column structure. I need a 24 column grid to allow finer control, but need a gutter that's larger than 1 column. Is that possible?
#include with-layout(24) {
.col-1 {
#include span(17);
}
.col-2 {
#include span(7);
}
}
So something like #include with-layout(24 2col-gutter) { ... }

I realised that if you want the gutter to be a multiple of the column width (1 col, 2 col etc) then you can just use the pre and push options.
In my case I actually wanted the gutter to be twice the width of the column so this worked perfectly.
$susy: (
columns: 24,
gutters: 0
);
.col-1 {
#include span(17);
}
.col-2 {
#include span(5);
}
.col-1 + .col-2 {
#include pre(2);
}
Demo

You could try:
$my-layout: (
columns: 24,
gutters: 2,
);
#include with-layout($my-layout) {
.col-1 {
#include span(17);
}
.col-2 {
#include span(last 7);
}
}
If you want more or less gutter-space change the number of gutters.

Related

Text over picture

Is it possible to create text displayed on a picture with nana?
I tried this
int main() {
using namespace nana;
form fm;
place plc(fm);
picture pic(fm);
label lbl(fm, "LBL", true);
pic.load(paint::image("xxx.png"));
pic.caption("PIC");
pic.align::center, align_v::center);
lbl.transparent(true);
lbl.text_align(align::center, align_v::center);
plc.div("<<here>>");
plc["here"] << pic;
plc["here"] << lbl; // (1)
plc.collocate();
lbl.move(pic.pos());
fm.show();
exec();
}
But its shifting both to the left as nana creates a grid for 2 elements in the layout. Without adding it, so deleting (1), the label will not be shown in the layout at all.
I couldnt find any information on it online. nana::image::caption(std::string) method seems to be ignored
Is there a way to get two elements on top of each other, in a place of one element? My goal is make a picture of a waterdrop and then writing the humidity-% in the middle of it.
Thank you
Display your picture, then use nana::paint::graphics::string to write your text on top of the picture.
This
is produced by
#include <iostream>
#include <nana/gui.hpp>
#include <nana/gui/widgets/picture.hpp>
#include <nana/gui/widgets/label.hpp>
int main()
{
using namespace nana;
paint::image I("xxx.bmp");
if (I.empty())
{
msgbox err("Error");
err << "Cannot read image";
err.show();
exit(1);
}
form fm({50,50,400,700});
drawing dw(fm);
dw.draw([&I](paint::graphics& g)
{
I.paste(g, {0,0} );
g.string({200,400}, "THIS IS A TEST", colors::black);
});
fm.show();
exec();
}

Custom map overlays using Marble

I'm trying to create custom overlays in Marble while following this tutorial. My code is identical to the one in the example.
Everything seems ok, but somehow the generated layer is editable and I can click it and change its size.
I'd like it to be just static on the background with no way of interacting with it.
There doesn't seem to be any obvious flag to set or function to override (so that I could just ignore all user events).
Any ideas?
Code as requested:
#include <QDebug>
#include <QFileInfo>
#include <QApplication>
#include <QImage>
#include <marble/MarbleWidget.h>
#include <marble/GeoDataDocument.h>
#include <marble/GeoDataGroundOverlay.h>
#include <marble/GeoDataTreeModel.h>
#include <marble/MarbleModel.h>
using namespace Marble;
int main(int argc, char** argv) {
QApplication app(argc,argv);
QFileInfo inputFile( app.arguments().last() );
if ( app.arguments().size() < 2 || !inputFile.exists() ) {
qWarning() << "Usage: " << app.arguments().first() << "file.png";
return 1;
}
// Create a Marble QWidget without a parent
MarbleWidget *mapWidget = new MarbleWidget();
// Load the Satellite map
mapWidget->setMapThemeId( "earth/bluemarble/bluemarble.dgml" );
// Create a bounding box from the given corner points
GeoDataLatLonBox box( 55, 48, 14.5, 6, GeoDataCoordinates::Degree );
box.setRotation( 0, GeoDataCoordinates::Degree );
// Create an overlay and assign the image to render and its bounding box to it
GeoDataGroundOverlay *overlay = new GeoDataGroundOverlay;
overlay->setLatLonBox( box );
overlay->setIcon( QImage( inputFile.absoluteFilePath() ) );
// Create a document as a container for the overlay
GeoDataDocument *document = new GeoDataDocument();
document->append( overlay );
// Add the document to MarbleWidget's tree model
mapWidget->model()->treeModel()->addDocument( document );
mapWidget->show();
return app.exec();
}
Update:
You can programatically enable/disable plugins using RenderPlugin and setVisible:
QList<RenderPlugin *> renderPluginList = marbleWidget->renderPlugins();
for (RenderPlugin *renderPlugin : renderPluginList) {
if (std::find(plugin_list.begin(), plugin_list.end(), renderPlugin->nameId()) != plugin_list.end())
{
renderPlugin->setVisible(true);
}
else
{
renderPlugin->setVisible(false);
}
}
Where plugin_list is a std::vector<QString> of plugin nameId()s.
To disable just the Annotation plugin, you could use:
QList<RenderPlugin *> renderPluginList = mapWidget->renderPlugins();
for (RenderPlugin *renderPlugin : renderPluginList) {
if (renderPlugin->nameId() == "annotation")
{
renderPlugin->setVisible(false);
}
}
In case you are still experiencing this issue, one thing to check is whether you have the AnnotationPlugin (.dll if on Windows) in the plugins/ directory. This plugin allows for moving and resizing various features on the MarbleWidget map.

C++ / QML interactive combo box implementation

I have two combo boxes, the data for the second one being determined by that of the first one. The number of strings in the second combo box varies from 2 to 4. If I:
select a new string in the first combo box and
the last choice is selected
in the second combo box with a longer list than the previous list of
that box,
the currentString in the second combo box remains and overrides the correct text
For instance, if I select Scubapro in the first combo box (4 options in 2nd box) and Smart in the second combo box (the 4th option), then select any other choice in the first combo box again (< 4 options in 2nd box), the entry in the second combo box remains "Smart", which is inappropriate. The correct list is, however, loaded into the 2nd combo box. Inspection of the underlying stringlist also suggests that it contains the correct data. The problem appears to be the visual updating of the second combo box. The heart of the algorithm comes from Stackoverflow and is the generator called each time text in combo box 1 changes.
What can one do to rectify this?
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQuickWindow>
#include <QQuickView>
#include <QQuickItem>
#include <QStringListModel>
#include <QQmlContext>
#include <QDebug>
QStringList dat1, dat2, dat3;
QStringList vendorList;
class Generator : public QObject
Q_OBJECT
QStringListModel * m_model;
public:
Generator(QStringListModel * model) : m_model(model) {}
Q_INVOKABLE void generate(const QVariant & val) {
m_model->removeRows(0,m_model->rowCount()); // This has no effect
if (QString::compare(val.toString(), QString::fromStdString("Mares"), Qt::CaseInsensitive) == 0) {
m_model->setStringList(dat1);
}
else {
if (QString::compare(val.toString(), QString::fromStdString("ScubaPro"), Qt::CaseInsensitive) == 0) {
m_model->setStringList(dat2);
}
else
m_model->setStringList(dat3);
}
};
int main(int argc, char *argv[])
{
QStringListModel model1, model2;
generator(&model2);
dat1 << "Puck" << "Nemo" << "Matrix";
dat2 << "Aladin" << "Meridian" << "Galilio" << "Smart";
dat3 << "D4" << "D6";
vendorList << "Mares" << "Scubapro" << "Suunto" << "Shearwater";
model1.setStringList(vendorList);
QGuiApplication app(argc, argv);
QQuickView view;
QQmlContext *ctxt = view.rootContext();
ctxt->setContextProperty("model1", &model1);
ctxt->setContextProperty("model2", &model2);
ctxt->setContextProperty("generator", &generator);
view.setSource(QUrl("qrc:main.qml"));
view.show();
return app.exec();
}
#include "main.moc"
Here is the QML:
import QtQuick 2.0
import QtQuick.Controls 1.0
Rectangle {
width: 400; height: 300
Text { text: "Vendor"; }
Text {
x: 200
text: "Product"; }
ComboBox {
id: box2
objectName: "productBox"
x:200; y:25; width: 180
model: model2
textRole: "display"
}
ComboBox {
y:25; width: 180
id: box1
model: model1
textRole: "display"
onCurrentTextChanged: {
generator.generate(currentText)
}
}
}
Any comments are highly appreciated.
The ComboBox item does not react to changes performed under the hood to the model.
There are a couple of solutions to work around it.
A possible one is to reassign the model to itself at the end of the signal handler, by using the statement:
model = model;
As from the documentation:
Changing the model after initialization will reset currentIndex to 0.
Otherwise, you can explicitly set currentIndex to your preferred value or, even better, to -1.
In fact, from the documentation we have that:
Setting currentIndex to -1 will reset the selection and clear the text label.

Accessing the variables of a parent widget via a button

I'm trying to implement a default button. This button should access strings of the parent widget which is a dialog box which the button is found on. I pasted the relevant parts of the code below. What I want is to be able to place strings to their corresponding lineEdit's when default values is clicked. For example pulse_string goes to ui->pulse_freq and nr_pulsestring goes into ui->nr_pulses etc.
#include "settings.h"
#include "ui_settings.h"
#include <QLineEdit>
#include <QSlider>
#include <QSpinBox>
int pulse_freq = 25000;
int nr_pulses = 10;
int samp_freq = 150000;
int nr_samples = 2000;
int gain = 32;
int accumulate = 1;
int acq_start = 0;
Settings::Settings(QWidget *parent) :
QDialog(parent),
ui(new Ui::Settings)
{
QString pulse_string, nr_pulsestring, sampfreq_string, nr_samplestring, gain_string;
QString accumulate_string, acq_string;
}
Settings::~Settings()
{
delete ui;
}
void Settings::on_Default_Values_clicked()
{
ui->pulse_freq->setText("25000");
ui->nr_pulses->setText("10");
ui->samp_freq->setText("150000");
ui->nr_samples->setText("2000");
ui->gain->setText("32");
ui->accumulate->setText("1");
ui->acq_start->setText("0");
}
You can use something looking like follows:
ui->pulse_freq->setText(QString("%1").arg(pulse_freq));
Since it seems you are only using numbers it would be better using a spinbox to insert values, so you dont have to check if an input is a valid number, etc.

List of spinboxes, displaying only values changed

So, I have an extensive list of spinboxes (30) in one tab and a confirmation page on another tab.
How can I can display only the names and values of those above 0 in the confirmation page?
Not sure if it matters, I'm doing this in Qt.
If I were you, I would be writing something like this:
confirmationpage.cpp
#include <QString>
#include <QSpinBox>
#include <QList>
#include <QLabel>
...
void ConfirmationPage::displaySpinBoxNameValues()
{
QString myText;
// Get the spinboxes from your tab.
// Use pointer anywhere here if you use that
foreach (SpinBox spinbBox, SpinBoxList) {
if (spinBox.value() > 0) {
myText.append(QString("Name: ") + spinBox.text());
myText.append(QString("\tValue: ") + spinBox.value());
myText.append('\n');
}
}
if (myText.isEmpty())
myText.append("No QSpinBox has value greater than zero!\n");
// Could be a QLabel, etc.
myDisplayWidget.setText(myText);
}
...
You would need the following method documentations to understand the methods used for this:
QLabel text property
QLabel value property
You can obtain the list of spinboxes and iterate over them like:
QList<QSpinBox *> list = this->findChildren<QSpinBox *>();
foreach(QSpinBox *spin, list)
{
if(spin->value()>0)
{
QDebug()<< spin->objectName();
}
}
You can get the name of the object by objectName() if you have previously assigned names to your spinboxes by setObjectName(const QString &name) .