Question: How does one create in tkinter.ttk.Treeview a node where the toggling arrow of the node is replaced by a defined image? That is, how do I get from my second picture to the first picture as shown below.
Problem: The New Mexico Tech Guide showed that tkinter.ttk.Treeview can create a folder directory as shown below:
Using the tkinter.ttk.Treeview .insert() method with an "image" keyword, I am only able to achieve the below. An image does appear on the left of the node text, but the image does not replace the arrow toggling the opening and closing of the node to reveal its descendants. I had assumed the image defined by the "image" keyword would replace the toggling arrows. But this did not happen.
Test Code:
import os
import tkinter as tk
import tkinter.ttk as ttk
from PIL import Image, ImageTk
class App(ttk.Frame):
def __init__(self, master, path):
ttk.Frame.__init__(self, master)
self.tree = ttk.Treeview(self)
ysb = ttk.Scrollbar(self, orient='vertical', command=self.tree.yview)
xsb = ttk.Scrollbar(self, orient='horizontal', command=self.tree.xview)
self.tree.configure(yscroll=ysb.set, xscroll=xsb.set)
self.tree.heading('#0', text='Directory', anchor='w')
abspath = os.path.abspath(path)
i = './icon/Home-icon_16.gif'
self.root_pic = tk.PhotoImage(file=i)
root_node = self.tree.insert('', 'end', text=' Work Folder', open=True, image=self.root_pic)
l1_node = self.tree.insert(root_node, 'end', text='level 1', open=True)
l2_node = self.tree.insert(l1_node, 'end', text='level 2', open=True)
l3_node = self.tree.insert(l2_node, 'end', text='level 3', open=True)
l2a_node = self.tree.insert(l1_node, 'end', text='level 2a', open=True)
l3a_node = self.tree.insert(l2a_node, 'end', text='level 3a', open=True)
self.tree.grid(row=0, column=0)
ysb.grid(row=0, column=1, sticky='ns')
xsb.grid(row=1, column=0, sticky='ew')
self.grid()
root = tk.Tk()
path_to_my_project = os.getcwd()
app = App(root, path=path_to_my_project)
app.mainloop()
Home-icon_16.gif:
Related
I want to create a modal like in the picture when the button is pressed. How can I make this model with Discord.py or nextcord?
You can find examples for modals in Nextcord here:
https://github.com/nextcord/nextcord/blob/master/examples/modals/
class Pet(nextcord.ui.Modal):
def __init__(self):
super().__init__("Your pet") # Modal title
# Create a text input and add it to the modal
self.name = nextcord.ui.TextInput(
label="Your pet's name",
min_length=2,
max_length=50,
)
self.add_item(self.name)
# Create a long text input and add it to the modal
self.description = nextcord.ui.TextInput(
label="Description",
style=nextcord.TextInputStyle.paragraph,
placeholder="Information that can help us recognise your pet",
required=False,
max_length=1800,
)
self.add_item(self.description)
async def callback(self, interaction: nextcord.Interaction) -> None:
"""This is the function that gets called when the submit button is pressed"""
response = f"{interaction.user.mention}'s favourite pet's name is {self.name.value}."
if self.description.value != "":
response += f"\nTheir pet can be recognized by this information:\n{self.description.value}"
await interaction.send(response)
#bot.slash_command(
name="pet",
description="Describe your favourite pet",
guild_ids=[TESTING_GUILD_ID],
)
async def send(interaction: nextcord.Interaction):
# sending the modal on an interaction (can be slash, buttons, or select menus)
modal = Pet()
await interaction.response.send_modal(modal)
class Modal(ui.Modal, title="test title"):
firstfield = ui.TextInput(label="firstfield",placeholder="write here", style=discord.TextStyle.short)
secondfield = ui.TextInput(label="secondfield",placeholder="write here", style=discord.TextStyle.short)
thirdfield = ui.TextInput(label="thirdfield:",placeholder="write here", style=discord.TextStyle.short)
first_big_field = ui.TextInput(label="first_big_field:",placeholder="write here", style=discord.TextStyle.long)
second_big_field = ui.TextInput(label="second_big_field:",placeholder="write here", style=discord.TextStyle.long)
Then u can call Modal() where u want
This code should produce a window that has a datatable in the main area, and a top navigation bar with a
Navigation menu. It works as intended for a number of other uses. Buttons, text fields, dialogue boxes, etc. have no problem, the navigation menu pops out just as it is supposed to. But the second I add the table widget the toolbar menu no longer functions.
I've tried every combination that I can think of to no avail.
from kivymd.app import MDApp
from kivy.uix.screenmanager import Screen, ScreenManager
from kivy.lang import Builder
from kivymd.uix.datatables import MDDataTable
from kivy.metrics import dp
mgr = """
Screen:
NavigationLayout:
ScreenManager:
id: Landing_Manager
Screen:
BoxLayout:
orientation: 'vertical'
MDToolbar:
title: 'test'
left_action_items: [["menu", lambda x: nav_drawer.set_state("open")]]
elevation:9
ScreenManager:
id: Screen_Manager
NewScreen:
id: New_Screen
name: 'NewScreen'
manager: Screen_Manager
MDNavigationDrawer:
id: nav_drawer
BoxLayout:
orientation: 'vertical'
ScrollView:
MDList:
id: container
OneLineIconListItem:
text: 'Item 1'
on_press:
nav_drawer.set_state("close")
OneLineIconListItem:
text: 'Item 2'
on_press:
nav_drawer.set_state("close")
<NewScreen>
"""
class NewScreen(Screen):
def on_enter(self):
self.rows = 3
self.rowInfo = [('','item 1', 'info 1a', 'info1b'),
('','item 2', 'info 2a', 'info2b'),
('','item 3', 'info 3a', 'info3b')]
self.colHeaders = [('check col',dp(30)),
("data col 1",dp(40)),
("data col 2",dp(50)),
("data col 3", dp(20))]
table = MDDataTable(column_data = self.colHeaders,
check = True,
rows_num = self.rows,
row_data = self.rowInfo)
self.add_widget(table)
class LookBusyApp(MDApp):
def build(self):
self.screen = ScreenManager()
self.app = Builder.load_string(mgr)
self.screen.add_widget(NewScreen(name = 'NewScreen'))
return self.app
if __name__ == "__main__":
app = LookBusyApp()
app.run()
Thanks for any help.
So I tracked down the issue and have a fix. I don't know if it is the best fix but it seems to work.
In kivymd.uix.datatables the MDDataTable class was inheriting from BaseDialog, which didn't seem to like working with the screenmanager, I changed the inheriting to Screen and it works.
original:
from kivymd.uix.dialog import BaseDialog
.
.
.
class MDDataTable(BaseDialog):
updated:
from kivymd.uix.dialog import Screen
.
.
.
class MDDataTable(Screen):
Additionally, from the builder-> MDDataTable ->canvas these 2 lines needs to be removed:
Color:
rgba: root.theme_cls.bg_normal
I have two presentational components. The first, called Category simply renders a React Native ListView component after doing a bit of set-up work.
The second component, Book, simply displays the data as text, with an image that should be fetched through the network.
Unfortunately, the Image doesn't seem to be displaying at all. Can someone help me get the image to display? Below, please find the Category and Book component definition, as well as a sample of the props being past to Book.
Category.js
import React from 'react';
import { ListView, Text } from 'react-native';
import _ from 'lodash';
import { camelizeKeys } from 'humps';
import Book from './Book';
const Category = ({ category }) => {
let element;
if (!_.isEmpty(category)) { // if data is available
const ds = new ListView.DataSource({ rowHasChanged: (r1, r2) => r1 !== r2 });
const camelCasedBooks = camelizeKeys(category.results.books);
const data = ds.cloneWithRows(camelCasedBooks);
element = (
<ListView
dataSource={data}
enableEmptySections
renderRow={(book) => <Book {...book} />}
/>
);
} else { // if data is not available
element = (
<Text>Loading</Text>
);
}
return element;
};
Category.propTypes = {
category: React.PropTypes.object.isRequired,
};
export default Category;
Book.js
import React from 'react';
import { Image, Text, View } from 'react-native';
const Book = ({ author, bookImage, description, title }) =>
<View>
<Text>
{author}
</Text>
<Text>
{bookImage}
</Text>
<Text>
{description}
</Text>
<Text>
{title}
</Text>
<Image source={{ uri: bookImage }} />
</View>;
Book.propTypes = {
author: React.PropTypes.string.isRequired,
bookImage: React.PropTypes.string.isRequired,
description: React.PropTypes.string.isRequired,
title: React.PropTypes.string.isRequired,
};
export default Book;
Sample Book Props
{
author: "Vi Keeland",
bookImage: "https://s1.nyt.com/du/books/images/9781942215462.jpg",
description: "Reese dismisses a chance encounter with a smug stranger, until he turns out to be her new boss.",
title: "BOSSMAN"
}
When using images that come from a remote location (such as your bookImage you need to set an explicit width and height on the Image's style. This is due to the fact that there is not automatic way for react-native to know how big the images is going to be.
Check the Image documentation for strategies on calculating the Image's size before being rendered. In my experience however simply setting the width and height explicitely is enough most of the times.
How can get a list of all config args?
from tkinter import *
from tkinter import ttk
root=Tk()
root.config(**args)
root.mainloop()
I tried with:
help(root.config)
The output:
Help on method configure in module tkinter:
configure(cnf=None, **kw) method of tkinter.Tk instance
Configure resources of a widget.
The values for resources are specified as keyword
arguments. To get an overview about
the allowed keyword arguments call the method keys.
If by "config args" you mean all the configurable attributes of a particular widget, you can obtain them like this:
my_widget.config()
In other words, what you just need to do is calling the method config (or configure, which is simply an alias) without arguments, which returns a _dictionary with the attributes, their values and more of the widget.
You could also use the pprint function (from the pprint module) to print nicely the attributes, like in the following example:
from tkinter import *
from pprint import pprint
root = Tk()
pprint(root.config())
And the output is the following:
{'background': ('background',
'background',
'Background',
<border object: 'systemWindowBody'>,
'systemWindowBody'),
'bd': ('bd', '-borderwidth'),
'bg': ('bg', '-background'),
'borderwidth': ('borderwidth',
'borderWidth',
'BorderWidth',
<pixel object: '0'>,
0),
'class': ('class', 'class', 'Class', 'Toplevel', 'Tk'),
'colormap': ('colormap', 'colormap', 'Colormap', '', ''),
'container': ('container', 'container', 'Container', 0, 0),
'cursor': ('cursor', 'cursor', 'Cursor', '', ''),
'height': ('height', 'height', 'Height', <pixel object: '0'>, 0),
'highlightbackground': ('highlightbackground',
'highlightBackground',
'HighlightBackground',
<color object: 'systemWindowBody'>,
'systemWindowBody'),
'highlightcolor': ('highlightcolor',
'highlightColor',
'HighlightColor',
<color object: 'Black'>,
'Black'),
'highlightthickness': ('highlightthickness',
'highlightThickness',
'HighlightThickness',
<pixel object: '0'>,
0),
'menu': ('menu', 'menu', 'Menu', '', ''),
'padx': ('padx', 'padX', 'Pad', <pixel object: '0'>, <pixel object: '0'>),
'pady': ('pady', 'padY', 'Pad', <pixel object: '0'>, <pixel object: '0'>),
'relief': ('relief', 'relief', 'Relief', <index object: 'flat'>, 'flat'),
'screen': ('screen', 'screen', 'Screen', '', ''),
'takefocus': ('takefocus', 'takeFocus', 'TakeFocus', '0', '0'),
'use': ('use', 'use', 'Use', '', ''),
'visual': ('visual', 'visual', 'Visual', '', ''),
'width': ('width', 'width', 'Width', <pixel object: '0'>, 0)}
According to the documentation regarding the config method at effbot.org:
config(cnf=None, **kw)
Modifies one or more widget options.
If called without an argument, this method returns a dictionary containing the current settings for all widget options. For each option key in the dictionary, the value is either a five-tuple (option, option database key, option database class, default value, current value), or a two-tuple (option alias, option). The latter case is used for aliases like bg (background) and bd (border width).
Note that the value fields aren’t correctly formatted for some option types. See the description of the keys method for more information, and a workaround.
Thank you #Axl for your answer .
from tkinter import *
from pprint import pprint
root=Tk()
pprint(root.key())
this code also works for me .
I am new to mootools. What I want is to create a new element span and inject an image to it.
I wrote the following code but doesn't work:
var newElementVar = new Element('span', {
'id': 'id_namekhan',
'text': 'I am a new div'
});
var my_img = new Element ('img' , {
'src' :'uploading/'+json.get('fpath')+'' ,
'style' : 'width:50px; text-align:left'
}).inject(id_namekhan, 'top');
Even the text 'I am a new div' is not showing.
Thanks
Your problem is that you are trying to inject the image into the span using its ID, but the span hasn't been added to the page (DOM tree) yet. Try this:
var my_span = new Element('span', {'id': 'id_namekhan','text': 'I am a new div'});
var my_img = new Element ('img' , {'src' :'uploading/'+json.get('fpath')+'' , 'style' : 'width:50px; text-align:left' }).inject(my_span, 'top');
my_span.inject($('element')); // replace element with the ID of the element you wish to inject the span inside