Access Imported QML Component ID from Imported JS - import

I'm trying to access an included QML id through an included JavaScript function. And I get the error:
Reference error: textItem is not defined.
main.qml
import QtQuick 2.1
import "functions.js" as Logic
Rectangle {
anchors.fill: parent;
Button { }
MouseArea {
onClicked: Logic.changeText()
}
}
Button.qml
import QtQuick 2.1
Rectangle {
width: 100; height: 30
color: "black"
Text {
id: textItem
anchors.centerIn: parent
font.pointSize: 20
color: "white"
text: "Hello!"
}
}
functions.js
function changeText() {
textItem.text = "Goodbye!";
}
Is there any way to access an Imported QML's id scope from an imported JS file?

As folibis said, textItem is not accessible to functions.js. There are more problems with your code, though. The button whose text you want to change has no ID, so you can't change its text even if you wanted to.
Give the button an ID, and then pass the button to changeText():
import QtQuick 2.1
import "functions.js" as Logic
Rectangle {
anchors.fill: parent;
Button {
id: button
}
MouseArea {
onClicked: Logic.changeText(button)
}
}
The next problem is that your Button type doesn't expose a text property. You should make an alias to the text property of textItem:
import QtQuick 2.1
Rectangle {
width: 100; height: 30
color: "black"
property alias text: textItem.text
Text {
id: textItem
anchors.centerIn: parent
font.pointSize: 20
color: "white"
text: "Hello!"
}
}
Then the rest will work:
function changeText(button) {
button.text = "Goodbye!";
}

In order to reference something from other files (or inside the QML file), you need to think in terms of the QML tree (navigating through the tree with id property). With that being said, I would suggest the following changes:
import QtQuick 2.1
import "functions.js" as Logic
Rectangle {
id: rootRec
anchors.fill: parent;
Button {id: myButton}
MouseArea {
onClicked: Logic.changeText(myButton)
}
}
In Button.qml:
import QtQuick 2.1
Rectangle {
id: rootRec
width: 100; height: 30
color: "black"
property string text: "Hello"
Text {
id: textItem
anchors.centerIn: parent
font.pointSize: 20
color: "white"
text: rootRec.text
}
}
In "function.js" you reference it like this:
function changeText(buttonId) {
buttonId.text = "Goodbye!"; }

Related

Cannot override Material UI Typography fontWeight

I just started using Material UI and learning to customize the default theme. I tried changing default palette color and it worked but overriding the typography property was not working.
I am trying to fontWeight property of h3 variant. The default fontWeight for h3 variant is 400. I am changing it to 100 or 300 but it's not reflecting.
Here is my code
Component.js
return (
<Typography variant="h3" color="secondary">
Arc Development
</Typography>
)
theme.js
import {createMuiTheme} from "#material-ui/core";
const arcBlue = "#0B72B9";
const arcOrange = "#FFBA60";
export default createMuiTheme({
palette: {
common: {
blue: `${arcBlue}`,
orange: `${arcOrange}`,
},
primary: {
main: `${arcBlue}`
},
secondary: {
main: `${arcOrange}`
}
},
typography: {
h3: {
fontS: 0,
}
}
});
Ciao, to override Typography you have to define in your theme an object called overrides and then inside this object you have to define another object called MuiTypography and override the h3 variant like this:
export default createMuiTheme({
palette: {
common: {
blue: `${arcBlue}`,
orange: `${arcOrange}`,
},
primary: {
main: `${arcBlue}`
},
secondary: {
main: `${arcOrange}`
}
},
overrides: {
MuiTypography: {
h3: {
fontWeight: 100
}
}
}
});
And if you inspect the element, you will see:
Here a codesandbox example.

Qt 5.12 TableView Header Delegate

I've created this table view in Qt 5.12 with new TableView but I don't know how to create header for it, I read documentation there is no headerdelegate for it neither. Here some screenshot:
so how can i add headerDelegate for 5.12 TableView?
import QtQuick 2.12
import QtQuick.Controls 2.12
ApplicationWindow {
visible: true
ListModel{
id:tableModel
ListElement{
identifier:1
name:'value'
title: 'test'
}
ListElement{
identifier:2
name:'value2'
title: 'test2'
}
}
width:1000; height: 500
//
TableView {
id:trans
LayoutMirroring.enabled: true
LayoutMirroring.childrenInherit: true
anchors.fill: parent
columnSpacing: 1
rowSpacing: 1
clip: true
model: tableModel
delegate: Rectangle {
Row{
Rectangle{
implicitWidth: 100
implicitHeight: 50
Text{
text: identifier
}
}
Rectangle{
implicitWidth: 100
implicitHeight: 50
Text{
text:name
}
}
Rectangle{
implicitWidth: 100
implicitHeight: 50
Text{
text:title
}
}
}
}
}
}
and TableViewColumn didn't work
Qc.TableViewColumn{
title: 'id'
role: 'identifier'
width:100
}
i'm trying to set its header from c++ but sth is not ok with my code
class TableHelper : public QObject
{
Q_OBJECT
public:
Q_INVOKABLE void setTableHeader(QObject & table){
// get QTableView and Set QHeaderView
qDebug()<< "here";
}
};
main :
TableHelper th;
engine.rootContext()->setContextProperty("tableHelper",&th);
qml :
Component.onCompleted: {
tableHelper.setTableHeader(trans)
}
I have a break point in C++ code, but it never runs.

How to set color of the text in a cell programatically

Is is possible to set color of the text in a cell programmatically?
Well my scenario is i have some numbers filling in the data-grid. I want to color them according to their values. I'm kind of lost here because i didn't found a way to customize a single cell. I've tried the 'rowRender' but it doesn't accomplish my task since it only colors a row. What i want is to color a single cell.
Is it possible to do this.
Yes we can format the column according to the data. Please see the following example to understand how to achieve it,
import ReactDOM from "react-dom";
import React from "react";
import ReactDataGrid from "react-data-grid";
import "./styles.css";
class NameFormatter extends React.Component {
render() {
return (
<span className={this.props.dependentValues.id === 1 ? "red" : "green"}>
{this.props.value}
</span>
);
}
}
let columns = [
{
key: "id",
name: "Id",
getRowMetaData: row => row
},
{
key: "name",
name: "Name",
getRowMetaData: row => row,
formatter: NameFormatter
}
];
class App extends React.Component {
constructor() {
super();
this.state = {
data: [{ id: 1, name: "einsten" }, { id: 2, name: "newton" }]
};
this.rowGetter = this.rowGetter.bind(this);
this.getSize = this.getSize.bind(this);
}
rowGetter(rowIndex) {
let rows = this.getRows();
return rows[rowIndex];
}
getRows() {
return this.state.data;
}
getSize() {
return this.getRows().length;
}
render() {
return (
<ReactDataGrid
columns={columns}
rowsCount={this.getSize()}
rowGetter={this.rowGetter}
/>
);
}
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
Inorder to customize the column we need to write a formatter component,here Nameformatter is the formatter component for the name column .We can access the column value via this.props.value and the meta data(Other column values) through this.props.dependentValues.nameoffield in the formatter component.
See the working example

Re-use themed style blocks within a Material-UI components styles

Thinking of the concept of a SASS mixin, what would be the best approach to enable the re-use of style blocks that incorporate the current theme.
For example I have two components that import their respective styles:
Component 1
index
styles
Component 2
index
styles
Each component has a text block
Component 1
import { styles } from './styles'
....
<div className={classes.richText}>...</div>
Component 2
import { styles } from './styles'
....
<div className={classes.richText}>...</div>
The styles for richText are the same but I would rather not duplicate them in the imported styles file.
I would rather have a single file that exposes reusable CSS properties based on the theme.
The only way I can currently do this is by returning an object that I have passed the theme to e.g.
const RichText = (theme) => {
return {
fontWeight: 100,
color: theme.typography.body1.color
}
}
Then import this into the styles
Component 1
styles.js
import { RichText } from '../mixins/'
const styles = theme => ({
richText: {
...RichText(theme),
fontSize: '1rem'
}
Component 2
styles.js
import { RichText } from '../mixins/'
const styles = theme => ({
richText: {
...RichText(theme),
fontSize: '1.2rem'
}
Feels like there has to be a better way: utilising withTheme() maybe?
Let's say you want to custom a checkbox as below:
import { makeStyles } from '#material-ui/core/styles';
import CheckBox from '#material-ui/core/CheckBox';
const useStyles = makeStyles((theme) => ({
root: {
color: theme.status.danger,
'&$checked': {
color: theme.status.danger,
},
},
checked: {},
}));
function CustomCheckbox() {
const classes = useStyles();
return (
<Checkbox
defaultChecked
classes={{
root: classes.root,
checked: classes.checked,
}}
/>
);
}
And you want to reuse its style as many components as you can.
You have two options: ThemeProvider or export your custom style.
Changing the component's theme
Themes let you apply a consistent tone to your app. It allows you to customize all design aspects of your project in order to meet the specific needs of your business or brand.
import { createMuiTheme, ThemeProvider } from '#material-ui/core/styles';
import orange from '#material-ui/core/colors/orange';
const myTheme = createMuiTheme({
status: {
danger: orange[500],
},
});
export default function CustomStyles() {
return (
<ThemeProvider theme={myTheme}>
<CustomCheckbox />
</ThemeProvider>
);
}
Exporting your custom styles
Separate your components in a proper folder, i.e: ./assets/styles:
import { makeStyles } from '#material-ui/core/styles';
export const useCheckBoxStyles = makeStyles((theme) => ({
root: {
color: theme.status.danger,
'&$checked': {
color: theme.status.danger,
},
},
checked: {},
}));
And your components tree ./components:
import { useCheckBoxStyles } from './assets/styles';
function CustomCheckbox() {
const classes = useCheckBoxStyles();
return (
<Checkbox
defaultChecked
classes={{
root: classes.root,
checked: classes.checked,
}}
/>
);
}
References
https://material-ui.com/customization/theming

BlackBerry10 cascades :cannot access control objects from QML in c++

In my project, I have two qml files viz. main.qml and DetailsPage.qml.
I am trying to change the text of a label of DetailsPage.qml from c++ using findChild() method.
This is the code in c++ file and DetailsPage.qml
Myfile.cpp code:
using namespace bb::cascades;
AbstractPane *root;
AbstractPane *root1;
Navigater::Navigater
(bb::cascades::Application *app):QObject(app)
{
QmlDocument *qml = QmlDocument::create("asset:///main.qml").parent(this);
QmlDocument *qml1 = QmlDocument::create("asset:///DetailsPage.qml").parent(this);
qml->setContextProperty("_app", this);
qml1->setContextProperty("_app", this);
root = qml->createRootObject<AbstractPane>();
root1 = qml1->createRootObject<AbstractPane>();
app->setScene(root);
}
void Navigater::tr1()
{
Label *tryLabel1 = root1->findChild<Label*>("labelObj");
if(tryLabel1)
{
qDebug()<<"tttt "<<tryLabel1->text(); //initial text
tryLabel1->setText("Hello!!!!!!!") ;
qDebug()<<"yyyy "<<tryLabel1->text(); //changedText gets reflected on DeviceLog but not on UI
}
else
{
qDebug()<<"Not Found";}
}
DetailsPage.qml code:
// Navigation pane project template
import
bb.cascades 1.0
Page
{
// page with a picture detail
id: pgDetail
actions: [
ActionItem {
title: qsTr("Break")
onTriggered: {
_app.tr1();
imgView.imageSource = "asset: //images/picture1br.png"
}
}
]
paneProperties: NavigationPaneProperties {
backButton: ActionItem {
onTriggered: {
navigationPane.pop()
}
}
}
onCreationCompleted: {
_app.tr1();
}
Container {
background: Color.Black
Label {
objectName: "labelObj" // control to be found
text: "Page 2"
horizontalAlignment: HorizontalAlignment.Center
textStyle {
base: SystemDefaults.TextStyles.TitleText
color: Color.Yellow
}
}
ImageView {
id: imgView
imageSource: "asset:///images/picture1.png"
horizontalAlignment: HorizontalAlignment.Center
}
Label {
text: qsTr("Picture description")
horizontalAlignment: HorizontalAlignment.Center
}
}
}
Change I have made is not getting reflected in simulator...but visible on device log.
Is there any way to access control objects from multiple pages i.e pages other than main.qml?
Could you please look into it.
You can use a navigation pane, add main.qml as page contents and details page as attachedObjects in the navigation pane like
attachedObjects: [
ComponentDefinition {
id: secondPageDefinition
source: "DetailsPage.qml"
}
in main page action add
onClicked: {
// show detail page when the button is clicked
var page = secondPageDefinition.createObject();
navigationPane.push(page);
}
i think this will solve your issue and in the main.cpp page change the content as follows
QmlDocument *qml = QmlDocument::create("asset:///main.qml").parent(this);
qml->setContextProperty("_app", this);
root = qml->createRootObject<AbstractPane>();
app->setScene(root);
and
void Navigater::tr1()
{
Label *tryLabel1 = root ->findChild<Label*>("labelObj");
if(tryLabel1)
{
qDebug()<<"tttt "<<tryLabel1->text(); /////////////intial text
tryLabel1->setText("Hello!!!!!!!") ;
qDebug()<<"yyyy "<<tryLabel1->text(); ////////////changedText gets reflected on DeviceLog but not on UI
}
else
{
qDebug()<<"Not Found";}
}
you can navigate in qml easily without using c++
1.page1.qml
Page {
id: rootPage
Container {
background: Color.LightGray
layout: DockLayout {
}
Label {
text: "First page"
horizontalAlignment: HorizontalAlignment.Center
verticalAlignment: VerticalAlignment.Center
}
}
actions: [
ActionItem {
title: "Next page"
ActionBar.placement: ActionBarPlacement.OnBar
onTriggered: {
var page = pageDefinition.createObject();
navigationPane.push(page);
}
attachedObjects: ComponentDefinition {
id: pageDefinition
source: "PageTwo.qml"
}
}
]
}
onPopTransitionEnded: {
page.destroy();
}