I am stuck with input with submit

i am looking for an example code plz help me

suppose i placed input with TUI and a submit button how do i provide connection between submit and input

class Stopwatch(Static):
def on_button_pressed(self, event: Button.Pressed) → None:
if event.button.id == “done”:
self.submit(“Input”)

def compose(self) -> ComposeResult:
    yield Input(placeholder="Data which u want to submit")
    yield Button("Submit", id="done", variant="success")

If you look at the docs for Input you’ll see that there are some attributes on the object that are “reactive” variables. One of these is called “value” and has the current value of the text input widget.

so you should be able to do self.submit(self.query_one(Input).value)

This will “find” the Input object and get the value from it. You can also store the Input object in a variable for later reference which is often convenient, like

def compose(self):
    self.saved_input = Input(placeholder="Data which u want to submit")
    yield self.saved_input
    yield Button("Submit", id="done", variant="success")

then later you can just use self.saved_input.value

2 Likes

i am really thank u alot u help me searching like 3-4hr lol

what if their two input how do we call specific input

def compose(self):
self.saved_input = Input(placeholder=“Data 1 to submit”)
self.saved_input = Input(placeholder=“Data 2 to submit”)
yield self.saved_input
yield Button(“Submit”, id=“done”, variant=“success”) // do we need to type

self.submit(self.specificid(Input).value)

if so then how can combine two query together
is it correct way calling them together so both trigger same time via button

def on_button_pressed(self, event: Button.Pressed) -> None:
    if event.button.id == "done":
    self.submit(self.query_one(Input).value)
    self.submit(self.query_two(Input).value)

So I’m guessing you have a somewhat low familiarity with python objects/classes/etc, which is fine. I’ll give a few relevant pieces of information which you may already know, just in case.

When you do something like
self.foo = Bar()
you are making a new instance of the class Bar and saving it as an attribute on the object self which is an object of the class your function is in.

So for 2 inputs, you could use something like

def compose(self):
    self.input1 = Input(placeholder="Data 1")
    self.input2 = Input(placeholder="Data 2")
    yield self.input1
    yield self.input2
    yield Button("Submit")

so now your button press function can look like

def on_button_pressed(self, event: Button.Pressed) → None:
    if event.button.id == “done”:
        self.submit(val1=self.input1.value, val2=self.input2.value)

So that’s one method - saving the Input objects to refer to later. The other method is the query_one() method. query_one is a Textual member function that will look for one matching object contained within the current widget tree.
self.query_one(Input) worked before, because there was only one Input, so it would only find one. It won’t work with 2, because you’re telling it to find one Input but there are 2.

So if you want to use the query method, then you need to set up your Input objects so that they can be distinct from one another. You can read about query_one and DOM selectors here

The basic idea is, you can create the Inputs like

def compose(self):
    yield Input(placeholder="data 1", id="input1")
    yield Input(placeholder="data 2", id="input2")
    yield Button("Submit", id="done", variant="success")

so then later you could find each Input like

val1 = self.query_one("#input1").value
val2 = self.query_one("#input2").value

There are a variety of ways to do these queries and set up widgets to be findable. I usually prefer to use the first method, where I save the object in the compose() method to refer to later, but either works.

1 Like

nvm i guess it working great but i want to know how do i print(val1) since it always open UI unable to see data pass or not

Take a look at the textual console. There’s some docs here:

Basically in one terminal window you run
textual console
and in the other you run
textual run --dev ./path/to/app.py

Outputs from print statements will show up in the console, along with mounting/unmounting of widgets, events being fired, actions running etc. It’s very useful for troubleshooting an application.

1 Like

amazing bro may the god bless on u got my all answer ^_^/

I know it is possible to use verbosity to increase the amount of logging which happens for the textual console. But there is no way to decrease instead of increase that, right?

I have the issue, that the print statements sometimes get lost in the logs. So I use several distinct print statements like:

print("----------------")
print("[whatever]")
print("----------------")

Btw.: Might be worth to be a separate post?

1 Like

really getting too hard to find logs or like impossible my brain get rolling lol is their a way to hide all these and only see print and log console

[14:47:21] PRINT                                                                                                                                                                                 kangroo.py:13

[14:47:21] PRINT                                                                                                                                                                                 kangroo.py:14
----------------
[14:47:21] PRINT                                                                                                                                                                                 kangroo.py:15
----------------
[14:47:21] INFO                                                                                                                                                                                  kangroo.py:16
----------------
[14:47:21] INFO                                                                                                                                                                                  kangroo.py:17
asd
[14:47:24] EVENT        ````

        print("----------------")
        print("[whatever]")
        print("----------------")
        print("----------------")
        log("----------------")
        log(self.data[1])

thanks man this really brilliant way

when you run the console there’s an option to eliminate any of the message events. You run it like textual console -x FOO where FOO is the type of log message you want to eliminate. Like in your screenshot you have a lot of EVENT logs so you could do textual console -x EVENT

2 Likes

what are these thing → None:

how do i do these thing on tui

def get_data(msg: str, in_msg: str):
    n = int(input(msg))
    channel = [input(in_msg.format(i)) for i in range(n)]
    return channel
c = get_data(f'Enter Amount of command in Number:', f'Enter KeyBoard Shortcut')```
        self.input2 = int(input('Enter the number of data : '))
        for i in range(self.input2):
            self.raw = input('Enter data ' + str(i) + ' : ')

        yield self.raw``` something similar to these how can we achieve that

-> None: specifies the return type of the function. Python does not need type specifications, but with tools like mypy it could improve the code quality/stability. It also helps “new” readers so they know what to expect. Again, this is not necessary to do, but textual (and other packages like fastAPI) use it a lot.

The other question is rather hard for me to understand. But if you want to have an input, like a keyboard input, you can either react on the key events, or use the input widget directly.

1 Like

I also don’t understand what you’re asking for. Can you explain what you’re trying to achieve?

    os.startfile(tesla)
    time.sleep(int(timeleft))
    channel = ['alt+f12', '', 'enter', 'enter', 'shift+esc']
    channel2 = ['', root, 'npm run dev', '', '']
    channel_all = zip(channel, channel2)
    for thing1, thing2 in channel_all:
        if thing1 != "":
            time.sleep(0.5)
            keyboard.send(thing1)
            time.sleep(0.5)
        if thing2 != "":
            keyboard.write(thing2)

i maked this channel 1 and channel 2 dynamic

from textual.app import App, ComposeResult
from textual.containers import Container
from textual.reactive import Reactive
from textual.widgets import Button, Header, Footer, Static, Input
from textual import log
import keyboard
import pickle
import os
import time

filename = 'data.dat'


class TeslaClass(Static):
    def my_function(self):
        self.byte_str = bytes(self.teslav .encode())
        self.teslaz = self.byte_str.replace(b"\x00", b"")
        os.startfile(self.teslaz)
        time.sleep(self.timeleft)
        channel = ['alt+f12', '', 'enter', 'enter', 'shift+esc']
        channel2 = ['', self.root, 'npm run dev', '', '']
        channel_all = zip(channel, channel2)
        for thing1, thing2 in channel_all:
            if thing1 != "":
                time.sleep(0.5)
                keyboard.send(thing1)
                time.sleep(0.5)
            if thing2 != "":
                keyboard.write(thing2)

    def submit(self):
        self.teslav = self.data[0]
        self.root = self.data[1]
        self.timeleft = int(self.data[2])
        self.yolo = [self.teslav, self.root, self.timeleft]
        with open(filename, 'wb') as f:
            pickle.dump(self.yolo, f)
        print("----------------")
        print("[whatever]")
        print("----------------")
        print("----------------")
        log("----------------")
        log(self.teslav)
        log(self.timeleft)
        self.my_function()

    def on_button_pressed(self, event: Button.Pressed) -> None:
        """Event handler called when a button is pressed."""
        try:
            with open(filename, 'rb') as file:
                user_input = pickle.load(file)
                data2 = user_input
                if data2 != "":
                    if event.button.id == "time_arc":
                        self.teslav = str(data2[0])
                        self.root = str(data2[1])
                        self.timeleft = int(data2[2])
                        self.add_class("started")
                        self.my_function()
                    elif event.button.id == 'done':
                        self.remove_class("started")

                else:
                    if event.button.id == "send":
                        self.data = [self.input1.value, self.input2.value, self.input3.value]
                        self.add_class("started")
                        self.submit()

                    elif event.button.id == 'done':
                        self.remove_class("started")
        except FileNotFoundError:
            with open(filename, 'wb') as file:
                pickle.dump('', file)

        except EOFError:
            print('not have data')

    def __init__(self):
        super().__init__()
        self.timeleft = None
        self.teslaz = 'dc'
        self.teslav = None
        self.yolo = None
        self.byte_str = None
        self.root = None
        self.input3 = None
        self.input2 = None
        self.input1 = None
        self.data = None

    def compose(self):
        self.input1 = Input(placeholder="drag ur file .exe or shortcut:")
        self.input2 = Input(placeholder="put ur cd location where npm script run:")
        self.input3 = Input(placeholder="how much time taken to open file type-in-second:")
        yield self.input1
        yield self.input2
        yield self.input3
        yield Button("Submit", id="send", variant="success")
        yield Button("Done", id="done", variant="error")
        yield Button("lastSavedDATA", id="time_arc", variant="error")


class TeslaApp(App):
    CSS_PATH = 'Stealth.css'
    BINDINGS = [("d", "toggle_dark", "Toggle dark mode")]

    def compose(self) -> ComposeResult:
        yield Header()
        yield Footer()
        yield Container(TeslaClass())

    def action_toggle_dark(self) -> None:
        self.dark = Reactive(not self.dark)


if __name__ == "__main__":
    app = TeslaApp()
    app.run()

the problem is that i dont understand how can i dynamically add LastSavedData 1 2 3 so on whenever user try to create since i can simply loop on data { 1,2 in data2} but how do i dynamically update those button also the another problem is that how do i add array data update on channel 1 and channel 2

the problem yet i face this code i cannot drag my file onto input making need to type instead on file exe or txt etc location which i want to execute

Honestly I have no idea what you’re trying to do, or what you want the user to be able to do. Your other thread honestly isn’t shedding that much light on it for me. Sorry.

I expect there is probably not an easy way to drag files into the console also, but idk

1 Like

is this method is not possible on tui?

        self.input2 = int(input('Enter the number of data : '))
        for i in range(self.input2):
            self.input3= input('Enter data ' + str(i) + ' : ')```