Compare commits
7 Commits
customtk-f
...
code-edito
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bdd3bab3a5 | ||
|
|
53aaa8a670 | ||
|
|
64631caaaa | ||
|
|
8e1f042350 | ||
|
|
128a7c49b9 | ||
|
|
e0fa421459 | ||
|
|
d64f87847c |
@@ -30,7 +30,7 @@ https://github.com/user-attachments/assets/ac91aa98-843d-4578-b646-88e66bc113de
|
|||||||
<sub>**Don't like background music? fell free to mute it**</sub>
|
<sub>**Don't like background music? fell free to mute it**</sub>
|
||||||
|
|
||||||
## Try PyUIBuilder
|
## Try PyUIBuilder
|
||||||
Try [PyUIBuilder](https://pyuibuilder.pages.dev/)
|
Try [PyUIBuilder](https://pyuibuilder.com)
|
||||||
|
|
||||||
## Table of contents
|
## Table of contents
|
||||||
|
|
||||||
@@ -53,7 +53,7 @@ Try [PyUIBuilder](https://pyuibuilder.pages.dev/)
|
|||||||
|
|
||||||
|
|
||||||
## Docs - Getting started
|
## Docs - Getting started
|
||||||
Read the docs on the [Docs page](https://pyuibuilder-docs.pages.dev/)
|
Read the docs on the [Docs page](https://docs.pyuibuilder.com/)
|
||||||
|
|
||||||
## Example app
|
## Example app
|
||||||
|
|
||||||
@@ -109,7 +109,7 @@ While there are a lot of features, here are few you need to know.
|
|||||||
* Framework agnostic - Can outputs code in multiple frameworks.
|
* Framework agnostic - Can outputs code in multiple frameworks.
|
||||||
* Pre-built UI widgets
|
* Pre-built UI widgets
|
||||||
* Plugins to extend 3rd party UI libraries
|
* Plugins to extend 3rd party UI libraries
|
||||||
* Supports layout managers, such as flex, grid and absolute positioning [read docs](https://pyuibuilder-docs.pages.dev/)
|
* Supports layout managers, such as flex, grid and absolute positioning [read docs](https://docs.pyuibuilder.com/)
|
||||||
* Generates python Code.
|
* Generates python Code.
|
||||||
* Support to upload local assets.
|
* Support to upload local assets.
|
||||||
* Generates requirements.txt file when needed
|
* Generates requirements.txt file when needed
|
||||||
|
|||||||
@@ -249,7 +249,7 @@
|
|||||||
|
|
||||||
</ul>
|
</ul>
|
||||||
<a
|
<a
|
||||||
href="https://pyuibuilder.pages.dev/"
|
href="https://pyuibuilder.com"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noreferrer noopener"
|
rel="noreferrer noopener"
|
||||||
class=" !tw-bg-[#0F1727] tw-duration-[0.3s] hover:tw-transition-transform hover:tw-scale-[1.01] !tw-mt-auto !tw-text-white tw-gap-2 tw-text-lg tw-rounded-md tw-w-full tw-flex tw-place-content-center tw-p-2 tw-mx-2"
|
class=" !tw-bg-[#0F1727] tw-duration-[0.3s] hover:tw-transition-transform hover:tw-scale-[1.01] !tw-mt-auto !tw-text-white tw-gap-2 tw-text-lg tw-rounded-md tw-w-full tw-flex tw-place-content-center tw-p-2 tw-mx-2"
|
||||||
|
|||||||
@@ -216,6 +216,7 @@ class Widget extends React.Component {
|
|||||||
this.resizeObserver = null
|
this.resizeObserver = null
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
@@ -704,8 +705,7 @@ class Widget extends React.Component {
|
|||||||
}
|
}
|
||||||
|
|
||||||
getLayout(){
|
getLayout(){
|
||||||
|
return this.getAttrValue("layout") || {layout: Layouts.PLACE}
|
||||||
return this.getAttrValue("layout") || Layouts.PLACE
|
|
||||||
}
|
}
|
||||||
|
|
||||||
setLayout(value) {
|
setLayout(value) {
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
export const Tkinter_TO_WEB_CURSOR_MAPPING = {
|
export const Tkinter_TO_WEB_CURSOR_MAPPING = {
|
||||||
|
|
||||||
|
"": "",
|
||||||
"arrow": "default",
|
"arrow": "default",
|
||||||
"circle": "wait",
|
"circle": "wait",
|
||||||
"clock": "wait",
|
"clock": "wait",
|
||||||
|
|||||||
@@ -686,9 +686,14 @@ export class CustomTkBase extends Widget {
|
|||||||
setLayout(value) {
|
setLayout(value) {
|
||||||
const { layout, direction, grid = { rows: 1, cols: 1 }, gap = 10, align } = value
|
const { layout, direction, grid = { rows: 1, cols: 1 }, gap = 10, align } = value
|
||||||
|
|
||||||
|
const gridRow = this.getAttrValue("gridConfig.noOfRows") || 3 // suppose its loaded using this.load, we need this
|
||||||
|
const gridCol = this.getAttrValue("gridConfig.noOfCols") || 3
|
||||||
|
|
||||||
if (layout === Layouts.GRID){
|
if (layout === Layouts.GRID){
|
||||||
|
|
||||||
|
const rowWeight = this.getAttrValue("gridWeights.rowWeights") || undefined // suppose its loaded via this.load
|
||||||
|
const colWeight = this.getAttrValue("gridWeights.colWeights") || undefined // suppose its loaded via this.load
|
||||||
|
|
||||||
|
|
||||||
const {...restAttrs} = this.state.attrs
|
const {...restAttrs} = this.state.attrs
|
||||||
|
|
||||||
@@ -702,7 +707,7 @@ export class CustomTkBase extends Widget {
|
|||||||
label: "No of rows",
|
label: "No of rows",
|
||||||
tool: Tools.NUMBER_INPUT,
|
tool: Tools.NUMBER_INPUT,
|
||||||
toolProps: { placeholder: "no of rows", max: 1000, min: 1 },
|
toolProps: { placeholder: "no of rows", max: 1000, min: 1 },
|
||||||
value: 3,
|
value: gridRow,
|
||||||
onChange: (value) => {
|
onChange: (value) => {
|
||||||
this.setAttrValue("gridConfig.noOfRows", value)
|
this.setAttrValue("gridConfig.noOfRows", value)
|
||||||
|
|
||||||
@@ -728,7 +733,7 @@ export class CustomTkBase extends Widget {
|
|||||||
label: "No of cols",
|
label: "No of cols",
|
||||||
tool: Tools.NUMBER_INPUT,
|
tool: Tools.NUMBER_INPUT,
|
||||||
toolProps: { placeholder: "no of cols", max: 1000, min: 1 },
|
toolProps: { placeholder: "no of cols", max: 1000, min: 1 },
|
||||||
value: 3,
|
value: gridCol,
|
||||||
onChange: (value) => {
|
onChange: (value) => {
|
||||||
this.setAttrValue("gridConfig.noOfCols", value)
|
this.setAttrValue("gridConfig.noOfCols", value)
|
||||||
|
|
||||||
@@ -752,7 +757,7 @@ export class CustomTkBase extends Widget {
|
|||||||
// placeholder: "weight",
|
// placeholder: "weight",
|
||||||
// defaultWeightMapping: this.getAttrValue("gridWeights.rowWeights"),
|
// defaultWeightMapping: this.getAttrValue("gridWeights.rowWeights"),
|
||||||
},
|
},
|
||||||
value: undefined,
|
value: rowWeight,
|
||||||
Component: DynamicGridWeightInput,
|
Component: DynamicGridWeightInput,
|
||||||
onChange: (value) => {
|
onChange: (value) => {
|
||||||
|
|
||||||
@@ -780,7 +785,7 @@ export class CustomTkBase extends Widget {
|
|||||||
// placeholder: "weight",
|
// placeholder: "weight",
|
||||||
// defaultWeightMapping: {0: {weight: 0, gridNo: 0}}
|
// defaultWeightMapping: {0: {weight: 0, gridNo: 0}}
|
||||||
},
|
},
|
||||||
value: undefined,
|
value: colWeight,
|
||||||
Component: DynamicGridWeightInput,
|
Component: DynamicGridWeightInput,
|
||||||
onChange: (value) => {
|
onChange: (value) => {
|
||||||
|
|
||||||
@@ -811,8 +816,6 @@ export class CustomTkBase extends Widget {
|
|||||||
}else if (layout === Layouts.FLEX){
|
}else if (layout === Layouts.FLEX){
|
||||||
const {gridConfig, gridWeights, ...restAttrs} = this.state.attrs
|
const {gridConfig, gridWeights, ...restAttrs} = this.state.attrs
|
||||||
|
|
||||||
console.log("Flex: ", restAttrs)
|
|
||||||
|
|
||||||
this.updateState((prevState) => ({attrs: {...restAttrs}}))
|
this.updateState((prevState) => ({attrs: {...restAttrs}}))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -886,6 +889,18 @@ export class CustomTkBase extends Widget {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getToolbarAttrs(){
|
||||||
|
const {layout, gridConfig, gridWeights, ...toolBarAttrs} = super.getToolbarAttrs()
|
||||||
|
|
||||||
|
// places layout at the end
|
||||||
|
return ({
|
||||||
|
id: this.__id,
|
||||||
|
...toolBarAttrs,
|
||||||
|
layout,
|
||||||
|
gridConfig,
|
||||||
|
gridWeights
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
serialize(){
|
serialize(){
|
||||||
return ({
|
return ({
|
||||||
@@ -938,6 +953,7 @@ export class CustomTkBase extends Widget {
|
|||||||
pos
|
pos
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const {layout} = attrs
|
||||||
|
|
||||||
this.setState(newData, () => {
|
this.setState(newData, () => {
|
||||||
let layoutAttrs = this.setParentLayout(parentLayout).attrs || {}
|
let layoutAttrs = this.setParentLayout(parentLayout).attrs || {}
|
||||||
@@ -973,6 +989,10 @@ export class CustomTkBase extends Widget {
|
|||||||
if (selected){
|
if (selected){
|
||||||
this.select()
|
this.select()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (layout){
|
||||||
|
this.setLayout(layout)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -161,6 +161,20 @@ class Frame extends CustomTkBase{
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getToolbarAttrs(){
|
||||||
|
const {layout, gridConfig, gridWeights, ...toolBarAttrs} = super.getToolbarAttrs()
|
||||||
|
|
||||||
|
// places layout at the end
|
||||||
|
return ({
|
||||||
|
id: this.__id,
|
||||||
|
...toolBarAttrs,
|
||||||
|
padding: this.state.attrs.padding,
|
||||||
|
margin: this.state.attrs.margin,
|
||||||
|
layout,
|
||||||
|
gridConfig,
|
||||||
|
gridWeights
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
renderContent(){
|
renderContent(){
|
||||||
// console.log("bounding rect: ", this.getBoundingRect())
|
// console.log("bounding rect: ", this.getBoundingRect())
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
export const Tkinter_TO_WEB_CURSOR_MAPPING = {
|
export const Tkinter_TO_WEB_CURSOR_MAPPING = {
|
||||||
|
|
||||||
|
"": "",
|
||||||
"arrow": "default",
|
"arrow": "default",
|
||||||
"circle": "wait",
|
"circle": "wait",
|
||||||
"clock": "wait",
|
"clock": "wait",
|
||||||
|
|||||||
@@ -687,9 +687,13 @@ export class TkinterBase extends Widget {
|
|||||||
setLayout(value) {
|
setLayout(value) {
|
||||||
const { layout, direction, grid = { rows: 1, cols: 1 }, gap = 10, align } = value
|
const { layout, direction, grid = { rows: 1, cols: 1 }, gap = 10, align } = value
|
||||||
|
|
||||||
|
const gridRow = this.getAttrValue("gridConfig.noOfRows") || 3 // suppose its loaded using this.load, we need this
|
||||||
|
const gridCol = this.getAttrValue("gridConfig.noOfCols") || 3
|
||||||
|
|
||||||
if (layout === Layouts.GRID){
|
if (layout === Layouts.GRID){
|
||||||
|
|
||||||
|
const rowWeight = this.getAttrValue("gridWeights.rowWeights") || undefined // suppose its loaded via this.load
|
||||||
|
const colWeight = this.getAttrValue("gridWeights.colWeights") || undefined // suppose its loaded via this.load
|
||||||
|
|
||||||
const {...restAttrs} = this.state.attrs
|
const {...restAttrs} = this.state.attrs
|
||||||
|
|
||||||
@@ -703,7 +707,7 @@ export class TkinterBase extends Widget {
|
|||||||
label: "No of rows",
|
label: "No of rows",
|
||||||
tool: Tools.NUMBER_INPUT,
|
tool: Tools.NUMBER_INPUT,
|
||||||
toolProps: { placeholder: "no of rows", max: 1000, min: 1 },
|
toolProps: { placeholder: "no of rows", max: 1000, min: 1 },
|
||||||
value: 3,
|
value: gridRow,
|
||||||
onChange: (value) => {
|
onChange: (value) => {
|
||||||
this.setAttrValue("gridConfig.noOfRows", value)
|
this.setAttrValue("gridConfig.noOfRows", value)
|
||||||
|
|
||||||
@@ -729,7 +733,7 @@ export class TkinterBase extends Widget {
|
|||||||
label: "No of cols",
|
label: "No of cols",
|
||||||
tool: Tools.NUMBER_INPUT,
|
tool: Tools.NUMBER_INPUT,
|
||||||
toolProps: { placeholder: "no of cols", max: 1000, min: 1 },
|
toolProps: { placeholder: "no of cols", max: 1000, min: 1 },
|
||||||
value: 3,
|
value: gridCol,
|
||||||
onChange: (value) => {
|
onChange: (value) => {
|
||||||
this.setAttrValue("gridConfig.noOfCols", value)
|
this.setAttrValue("gridConfig.noOfCols", value)
|
||||||
|
|
||||||
@@ -753,7 +757,7 @@ export class TkinterBase extends Widget {
|
|||||||
// placeholder: "weight",
|
// placeholder: "weight",
|
||||||
// defaultWeightMapping: this.getAttrValue("gridWeights.rowWeights"),
|
// defaultWeightMapping: this.getAttrValue("gridWeights.rowWeights"),
|
||||||
},
|
},
|
||||||
value: undefined,
|
value: rowWeight,
|
||||||
Component: DynamicGridWeightInput,
|
Component: DynamicGridWeightInput,
|
||||||
onChange: (value) => {
|
onChange: (value) => {
|
||||||
|
|
||||||
@@ -781,7 +785,7 @@ export class TkinterBase extends Widget {
|
|||||||
// placeholder: "weight",
|
// placeholder: "weight",
|
||||||
// defaultWeightMapping: {0: {weight: 0, gridNo: 0}}
|
// defaultWeightMapping: {0: {weight: 0, gridNo: 0}}
|
||||||
},
|
},
|
||||||
value: undefined,
|
value: colWeight,
|
||||||
Component: DynamicGridWeightInput,
|
Component: DynamicGridWeightInput,
|
||||||
onChange: (value) => {
|
onChange: (value) => {
|
||||||
|
|
||||||
@@ -812,8 +816,6 @@ export class TkinterBase extends Widget {
|
|||||||
}else if (layout === Layouts.FLEX){
|
}else if (layout === Layouts.FLEX){
|
||||||
const {gridConfig, gridWeights, ...restAttrs} = this.state.attrs
|
const {gridConfig, gridWeights, ...restAttrs} = this.state.attrs
|
||||||
|
|
||||||
console.log("Flex: ", restAttrs)
|
|
||||||
|
|
||||||
this.updateState((prevState) => ({attrs: {...restAttrs}}))
|
this.updateState((prevState) => ({attrs: {...restAttrs}}))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -827,8 +829,8 @@ export class TkinterBase extends Widget {
|
|||||||
flexDirection: "column",
|
flexDirection: "column",
|
||||||
// flexDirection: direction,
|
// flexDirection: direction,
|
||||||
gap: `${gap}px`,
|
gap: `${gap}px`,
|
||||||
gridTemplateColumns: "repeat(3, max-content)",
|
gridTemplateColumns: `repeat(${gridRow}, max-content)`,
|
||||||
gridTemplateRows: "repeat(3, max-content)",
|
gridTemplateRows: `repeat(${gridCol}, max-content)`,
|
||||||
// gridTemplateColumns: "repeat(auto-fill, minmax(100px, auto))",
|
// gridTemplateColumns: "repeat(auto-fill, minmax(100px, auto))",
|
||||||
// gridTemplateRows: "repeat(auto-fill, minmax(100px, auto))",
|
// gridTemplateRows: "repeat(auto-fill, minmax(100px, auto))",
|
||||||
}
|
}
|
||||||
@@ -888,6 +890,19 @@ export class TkinterBase extends Widget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
getToolbarAttrs(){
|
||||||
|
const {layout, gridConfig, gridWeights, ...toolBarAttrs} = super.getToolbarAttrs()
|
||||||
|
|
||||||
|
// places layout at the end
|
||||||
|
return ({
|
||||||
|
id: this.__id,
|
||||||
|
...toolBarAttrs,
|
||||||
|
layout,
|
||||||
|
gridConfig,
|
||||||
|
gridWeights
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
serialize(){
|
serialize(){
|
||||||
return ({
|
return ({
|
||||||
...super.serialize(),
|
...super.serialize(),
|
||||||
@@ -939,6 +954,8 @@ export class TkinterBase extends Widget {
|
|||||||
pos
|
pos
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const {layout} = attrs
|
||||||
|
|
||||||
|
|
||||||
this.setState(newData, () => {
|
this.setState(newData, () => {
|
||||||
let layoutAttrs = this.setParentLayout(parentLayout).attrs || {}
|
let layoutAttrs = this.setParentLayout(parentLayout).attrs || {}
|
||||||
@@ -965,15 +982,21 @@ export class TkinterBase extends Widget {
|
|||||||
|
|
||||||
|
|
||||||
if (newAttrs?.styling?.backgroundColor){
|
if (newAttrs?.styling?.backgroundColor){
|
||||||
// TODO: find a better way to apply innerStyles
|
// TODO: find a better way to apply innerStyles (we may not need this anymore)
|
||||||
this.setWidgetInnerStyle("backgroundColor", newAttrs.styling.backgroundColor.value)
|
this.setWidgetInnerStyle("backgroundColor", newAttrs.styling.backgroundColor.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
this.updateState({ attrs: newAttrs }, callback)
|
this.updateState({ attrs: newAttrs }, callback)
|
||||||
|
|
||||||
// FIXME: when changing layouts all the widgets are being selected
|
// FIXME: when changing layouts all the widgets are being selected
|
||||||
if (selected){
|
if (selected){
|
||||||
this.select()
|
this.select()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (layout){
|
||||||
|
this.setLayout(layout)
|
||||||
|
}
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -161,7 +161,20 @@ class Frame extends TkinterBase{
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getToolbarAttrs(){
|
||||||
|
const {layout, gridConfig, gridWeights, ...toolBarAttrs} = super.getToolbarAttrs()
|
||||||
|
|
||||||
|
// places layout at the end
|
||||||
|
return ({
|
||||||
|
id: this.__id,
|
||||||
|
...toolBarAttrs,
|
||||||
|
padding: this.state.attrs.padding,
|
||||||
|
margin: this.state.attrs.margin,
|
||||||
|
layout,
|
||||||
|
gridConfig,
|
||||||
|
gridWeights
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
renderContent(){
|
renderContent(){
|
||||||
// console.log("bounding rect: ", this.getBoundingRect())
|
// console.log("bounding rect: ", this.getBoundingRect())
|
||||||
|
|||||||
Reference in New Issue
Block a user