mercredi 31 janvier 2024

Tkinter issue regarding dynamically uncheck CheckBoxes

In Tkinter (Python) I try to dynamically uncheck a CheckBox when an another CheckBox is checked but the behavior is rather erratic.

  1. If the first box is checked and i check the second one: the second box checks for few seconds then it unchecks. The event related to the second CheckBox doesn't trigger.
  2. If the second box is checked and i check the first one: the behavior is correct as it uncheck the second one and check the first one. The event related to the first CheckBox does trigger.
  3. If there's no single box checked and I check one box at the time the events do trigger normally.

My code :

import tkinter as tk

class App(tk.Tk):
    def __init__(self):
        super().__init__()

        self.frame = tk.Frame(self)
        self.frame.pack(fill=tk.BOTH, expand=True)

        self.entry1 = tk.Canvas(self.frame, width=100, height=100, highlightthickness=0, bd=0, bg="green", relief='solid')
        self.entry1.grid(row=0, column=0)

        self.entry2 = tk.Canvas(self.frame, width=100, height=100, highlightthickness=0, bd=0, bg="red", relief='solid')

        self.check_var1 = tk.BooleanVar()
        self.check_var1.set(True)
        self.check_box1 = tk.Checkbutton(self, text="Show Green", variable=self.check_var1, command=lambda: self.toggle_entries(self.check_var1))
        self.check_box1.pack()

        self.check_var2 = tk.BooleanVar()
        self.check_box2 = tk.Checkbutton(self, text="Show Red", variable=self.check_var2, command=lambda: self.toggle_entries(self.check_var2))
        self.check_box2.pack()

        self.check_var1.trace_add('write', self.check_var_changed)
        self.check_var2.trace_add('write', self.check_var_changed)

        self.toggle_entries(self.check_var1)

    def toggle_entries(self, var):
        if var is self.check_var1:
            if var.get():
                self.entry1.grid()
                self.entry2.grid_remove()
                self.check_var2.set(False) 
        elif var is self.check_var2:
            if var.get():
                self.entry2.grid()
                self.entry1.grid_remove()
                self.check_var1.set(False) 

    def check_var_changed(self, *args):
        if self.check_var1.get():
            self.check_var2.set(False)
        elif self.check_var2.get():
            self.check_var1.set(False)

if __name__ == "__main__":
    app = App()
    app.mainloop()

Any ideas of why this functiontoggle_entries doesn't work properly?




samedi 27 janvier 2024

TreeView Select parent checkbox based on children - WPF MVVM

I am new to WPF. I found a few examples and put together a tree-view example in C# WPF Mvvm. I got the children's checkboxes checked or unchecked based on parent selection. I am not sure how to access the parent binding or property to check or uncheck it based on children. If all children are selected, I expect parents to be checked, and if even one child is unchecked, I want parents to be unchecked. How do I achieve this using the MVVM viewmodel? Any suggestions would be greatly appreciated.

Xaml View

<Window x:Class="WpfApp1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:WpfApp1"
    mc:Ignorable="d"
    Title="MainWindow" Height="450" Width="800">
<Window.DataContext>
    <local:MainViewModel></local:MainViewModel>
</Window.DataContext>
<Window.Resources>
    <HierarchicalDataTemplate DataType="{x:Type local:CheckableItem}" ItemsSource="{Binding 
        Children, Mode=TwoWay}">
        <StackPanel Orientation="Horizontal">
            <CheckBox IsChecked="{Binding IsChecked, Mode=TwoWay}" Command="{Binding RelativeSource={RelativeSource AncestorType={x:Type TreeView}}, 
                                                Path=DataContext.CheckBoxCommand}" CommandParameter="{Binding}"/>
            <TextBlock Text="{Binding Name}"/>
        </StackPanel>
    </HierarchicalDataTemplate>
</Window.Resources>

<StackPanel>
    <Label Content="Miscellaneous Imports" HorizontalAlignment="Center" />
    <ScrollViewer>
        <TreeView ItemsSource="{Binding MiscellaneousImports, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" FontSize="10" Height="450"/>
    </ScrollViewer>
</StackPanel>

ViewModel

public class MainViewModel : INotifyPropertyChanged
{

    public event PropertyChangedEventHandler? PropertyChanged;

    public ICommand CheckBoxCommand { get; set; }
    public MainViewModel()
    {
        LoadCheckableItems();
        CheckBoxCommand = new DelegateCommand<CheckableItem>(OnCheckBoxChecked);
    }

    private void OnCheckBoxChecked(CheckableItem item)
    {
        throw new NotImplementedException();
    }

    private ObservableCollection<CheckableItem> miscellaneousImports;
    public ObservableCollection<CheckableItem> MiscellaneousImports
    {
        
        get { return miscellaneousImports; }
        set
        {
            miscellaneousImports = value;
            OnPropertyChanged("MiscellaneousImports");
        }
    }
    private void LoadCheckableItems()
    {
        List<CheckableItem> lstItems = new List<CheckableItem>();

        CheckableItem item = new CheckableItem
        { Name = "Coffee", Children = new ObservableCollection<CheckableItem>() { new CheckableItem { Name="Medium" }, new CheckableItem {Name="Dark" } } };
        lstItems.Add(item);

        MiscellaneousImports = new ObservableCollection<CheckableItem> ( lstItems );
    }
    protected void OnPropertyChanged(string propertyName)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

Checkbox collection class

public class CheckableItem:INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        private string _name;
        public string Name
        {
            get { return _name; }
            set
            {
                _name = value;
                OnPropertyChanged("Name");
            }
        }
        public ObservableCollection<CheckableItem> Children { get; set; }
        private bool _isChecked;
        public bool IsChecked
        {
            get { return _isChecked; }
            set
            {
                _isChecked = value;
                OnPropertyChanged("IsChecked");
                if (Children != null)
                {
                    foreach (CheckableItem child in Children)
                    {
                        child.IsChecked = IsChecked;
                    }
                    OnPropertyChanged(nameof(Children));
                }
            }
        }
        protected void OnPropertyChanged(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
     
    }



mardi 16 janvier 2024

How to have checkboxes checked by default using useFormik?

I have these components and I have 12 checkboxes in child component. I want to have them checked by default when the component loads. I can't do that. I can't use checked='true' as an attribute for my input because formik is controlling my input and it doesn't work well. Or I set checked attribute with some pre-defined values in checked array, but again it worked badly. I thought I probably can use useRef here to trigger onChange event of input to simulate changing checkboxes by checking them. something like this:

const ref = useRef();

useEffect(() => {
ref.current.change();
}, [])

and setting ref to the input. But this didn't work. How can I fix this problem with ref or something else?

    import {useFormik} from "formik";
    import CheckboxesComponent from "./CheckboxesComponent";
    
    const AddUserForm = ({handleShowForm, showForm, formTitle}) => {
        const cities = options.slice(1)
        const [textAreaString, setTextArea] = useState('')
    
        const formik = useFormik({
            initialValues: {
                tel: '', name: '', password: '', username: '', province: '', level: '', availableCities: '', city: '',
                checked: []
            },
            onSubmit: values => {
                console.log(formik.values)
            }
        })
    
        return(
            <form className='add-user-form' onSubmit={formik.handleSubmit}>
                <div className='form-flex'>
                   {/*other parts of form*/}
                </div>
                <CheckboxesComponent handleChange={formik.handleChange} />
            </form>
        )
    }
    export default AddUserForm

CheckBoxesComponent:

const fields = [
    {name: 'delNomad', label: 'حذف عشایر'},
    {name: 'editNomad', label: 'ویرایش عشایر'},
    {name: 'addNomad', label: 'افزودن عشایر'},
    {name: 'delDriver', label: 'حذف راننده'},
    {name: 'editDriver', label: 'ویرایش راننده'},
    {name: 'addDriver', label: 'افزودن راننده'},
    {name: 'rejectReq', label: 'رد درخواست ها'},
    {name: 'manualDeliver', label: 'تایید تحویل دستی'},
    {name: 'addWaterReq', label: 'افزودن درخواست آب'},
    {name: 'getExcel', label: 'دریافت فایل اکسل'},
    {name: 'seeingReport', label: 'مشاهده گزارش گیری'},
    {name: 'delReq', label: 'حذف درخواست ها'},
];

const CheckboxesComponent = ({handleChange}) => {

    return(
        <div className='checkboxes-part'>
            {fields.map((item, index) => {
                return(
                    <div>
                        <label>{item.label}</label>
                        <input type='checkbox' name='checked' value={item.name} onChange={handleChange} />
                    </div>
                )
            })}
        </div>
    )
}

export default CheckboxesComponent



dimanche 14 janvier 2024

I want to add a checkbox to Learndash checkout page

I a php and learndash beginner and need help. I would like to add a checkbox to the checkout page in learndash.

Can you have a hint which action hook will do. The checkbox should be added to the order overview page This page is shown after registration and has a buynow-button.

enter image description hereI have tried a lot of hooks without success.

Thanks a lot for your help




jeudi 11 janvier 2024

Using python, how can i check if a html checkbox is hidden, and if it's checked?

In an HTML form, I have a checkbox which class is 'hidden' or not, depending on the user's previous choices.

This is my HTML javascript code which creates the checkbox

const cityBusesLabel = document.createElement('label');
cityBusesLabel.textContent = `Use of city buses`;
const cityBusesInput = document.createElement('input');
cityBusesInput.type = 'checkbox';
cityBusesInput.name = `cityBuses ${venueNumber}-${originCounter}`;
cityBusesInput.id = `cityBusesInput ${venueNumber}-${originCounter}`;
cityBusesInput.classList.add('hidden');
cityBusesLabel.id = `cityBusesLabel ${venueNumber}-${originCounter}`;
cityBusesLabel.classList.add('hidden');
cityBusesLabel.appendChild(cityBusesInput);

And this is the HTML javascript code that shows / hides it :

document.getElementById('venue_location_' + venueNumber).addEventListener('input', function() { 
    const select_value = document.getElementById('venue_location_' + venueNumber).value;
    if (select_value === 'suburban') {
        document.getElementById('cityBusesInput ' + venueNumber + '-' + originCounter).classList.remove('hidden');
        document.getElementById('cityBusesLabel ' + venueNumber + '-' + originCounter).classList.remove('hidden');
    } else {
        document.getElementById('cityBusesInput ' + venueNumber + '-' + originCounter).classList.add('hidden');
        document.getElementById('cityBusesLabel ' + venueNumber + '-' + originCounter).classList.add('hidden');
    }
});

Now, in my app.py python code using Flask, I am trying to check first of all if the checkbox is hidden or not, and second of all if it's checked or not.

I tried writing :

cityBuses_checkbox = request.form.get(f'cityBuses {i}-{origin_counter}')
if cityBuses_checkbox :
    if cityBuses_checkbox == 'on' :
         city_buses.append(1)
    else :
         city_buses.append(0)

But it didn't give me the output I wanted. Is this the right way to do these two checks?