I'm learning from a book about making apps with Kivy and there's this block of code:
from kivy.app import App
from kivy.uix.textinput import TextInput
from kivy.uix.button import Button
from kivy.uix.boxlayout import BoxLayout
class TestApp(App):
press_count = 1
def button_press(self, button_pressed):
print('Button Pressed', TestApp.press_count, 'TImes')
TestApp.press_count += 1
def build(self):
my_btn = Button(text='Click Me')
my_btn.bind(on_press=TestApp.button_press)
textinput = TextInput(text='Data Inside TextInput')
box_layout = BoxLayout(orientation='vertical')
box_layout.add_widget(widget=my_btn)
box_layout.add_widget(widget=textinput)
return box_layout
if __name__ == '__main__':
TestApp().run()
when I run this I get understandably TypeError: button_press() missing 1 required positional argument: 'button_pressed' my question is why the author of the book isn't getting this error and the code runs ?
my_btn.bind(on_press=TestApp.button_press)
This is wrong, it should be my_btn.bind(on_press=self.button_press).
Related
I am trying to run the below code,
from kivymd.uix.screen import MDScreen
from kivymd.app import MDApp
from kivy.uix.image import Image
from kivymd.uix.button import MDFillRoundFlatIconButton, MDFillRoundFlatButton
from kivymd.uix.textfield import MDTextField
from kivymd.uix.label import MDLabel
from kivymd.uix.toolbar import MDToolbar
class ConverterApp(MDApp):
def build(self):
screen = MDScreen()
self.toolbar = MDToolbar(title = 'Binary to Decimal')
self.toolbar.pos_hint = {'top':1}
screen.add_widget(self.toolbar)
return screen
if __name__ == '__main__':
ConverterApp().run()
But seeing a output error, which is
from kivymd.uix.toolbar import MDToolbar
ImportError: cannot import name 'MDToolbar' from 'kivymd.uix.toolbar'
I even searched on google, regarding this module error, but didn't get the required answer.
Can anyone solve this issue?
I'm struggling to simultaneously run my Kivy app alongside a python script that is being locally imported.
Full python code
import Client # Locall import
import time
from threading import Thread
from kivy.app import App
from kivy.uix.button import Button
from kivy.lang import Builder
from kivy.uix.screenmanager import ScreenManager, Screen
class MainWindow(Screen):
pass
class SecondWindow(Screen):
pass
class WindowManager(ScreenManager):#will manage navigation of windows
pass
kv = Builder.load_file("my.kv")
class Sound(App):
def build(self):
return kv
def ipconfig(self,input_ip):
if len(input_ip) == 13:
print('Address binded!!')
Client.host = input_ip #Modify ip adress
else:
print('Invalid input_ip')```
if __name__ == '__main__':
#Sound().run()#Kivy run method
Thread(target = Sound().run()).start()
time.sleep(10)
Thread(target = Client.father_main).start()
Where the threading happens
if __name__ == '__main__':
#Sound().run()#Kivy run method
Thread(target = Sound().run()).start()
time.sleep(10)
Thread(target = Client.father_main).start() #Client is locally imported
PROBLEMS
1.Only the kivy app runs but the father_main function fails to.
2.The only time father_main runs is when I close the kivy application.
3.If i try and remove the 'run()' from Sound(). I get TypeError: 'Sound' object is not callable and father_main immediately runs
4.If i only remove the parenthesis from 'run()' so it turns into 'run'. I get Segmentation fault (core dumped)
kivy does not encourage the use of time.sleep() and i still have no clue of what exactly your program is but here a solution.
create an on_start method (A method that runs when kivy app started) and add start the ipconfig method from there but you're going to start it asynchronously.
from multiprocessing.pool import ThreadPool
class Sound(App):
def on_start(self):
pool = ThreadPool(processes=1)
async_start = pool.apply_async(self.ip_config, ("value for ip_input here"))
# do some other things inside the main thread here
if __name__ == "__main__":
Sound().run()
You need to run the App on the main thread. I would suggest something like:
def start_father_main(dt):
Thread(target = Client.father_main).start() #Client is locally imported
if __name__ == '__main__':
Clock.schedule_once(start_father_main, 10)
Sound().run()
I haven't tested this code, but it should give you the idea.
Code here (left out the unrelated Kivy stuff):
from kivy.app import App
from kivy.core.window import Window
from kivy.uix.widget import Widget
from configparser import ConfigParser
import os
class MIDIApp(App):
def build(self):
self.config = ConfigParser()
self.config.read('values.ini')
Window.size = Window.size
return MainWindow()
def input1_comp_move(self, value):
print(int(value))
def input1_save_comp_value(self, value):
self.config['Input1']['comp'] = str(value)
print(str(value))
with open('values.ini', 'w') as config_file:
ConfigParser.write(config_file)
print('Input1 comp value is ', value)
class MainWindow(Widget):
pass
if __name__ == '__main__':
MIDIApp().run()
When I run this I get the error ConfigParser.write(self.config_file)
TypeError: write() missing 1 required positional argument: 'fp'
And when I debug by leaving it blank it requires 2 positional arguments 'self' and 'filename', it didn't require that when I tried to used this another program. What am I missing?
It should be self.config.write(self.config_file) or, if you insist, ConfigParser.write(self.config, self.config_file).
Thanks ForceBru
So basically I have a kivy project in which,I have a layout that I use in many classes,as such..I have made in custom and put it in a separate file so I can just reference it from different parts of my code.
Snippet:
from kivy.uix.boxlayout import BoxLayout
from kivy.lang import Builder
Builder.load_string('''
<CustLayout>:
#code here
''')
class CustLayout(BoxLayout):
t_length = NumericProperty(0)
my_len = 0
print(my_len)
def __init__(self, **kwargs):
super(Silvertable,self).__init__(**kwargs)
self.bind(t_length=self.on_t_length)
#This statement is executed after all other prints
print(self.t_length)
def on_t_length(self,instance,length):
#I'd like to get kv file value before the next line
self.my_len = length
print(my_len)
My kiv file:
#:import Silvertable silvertables.Silvertable
#chunk of code
BoxLayout:
Silvertable:
t_length: 5
Here,I DO get the value but unfortunately too late.That is,I get the value after the program has finished.my_len Doesn't change it's still 0
Bind Kivy Properties
The value of my_len is 0 (zero) because the print() functions were executed first before the run() method.
The value of my_len did change from 0 to 5 as per binding on property of t_length.
Please refer to the example and trace for details.
Example
main.py
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.properties import NumericProperty
from kivy.lang import Builder
Builder.load_string('''
<CustLayout>:
t_length: 5
''')
class CustLayout(BoxLayout):
t_length = NumericProperty(0)
my_len = 0
print("\tCustLayout.class level-start: my_len=", my_len)
def __init__(self, **kwargs):
super(CustLayout,self).__init__(**kwargs)
print("\nCustLayout.__init__:")
self.bind(t_length=self.on_t_length)
#This statement is executed after all other prints
print("\tself.t_length=", self.t_length)
print("\tself.my_len=", self.my_len)
def on_t_length(self, instance, length):
print("\nCustLayout.on_t_length:")
#I'd like to get kv file value before the next line
self.my_len = length
print("\tself.my_len=", self.my_len)
print("\tCustLayout.class level-end: my_len=", my_len)
class TestBindProperty(App):
def build(self):
print("\nTestBindProperty.build:")
return CustLayout()
def on_stop(self):
print("\tTestBindProperty.on_stop: my_len=", self.root.my_len)
if __name__ == "__main__":
TestBindProperty().run()
Output
When i run python-pyside2 project server first, then it works well.
And the site also work well, but if i press F5 btn to refresh in browser.
Site shows error page Runtime at/
import sys
from urllib.request import urlopen
from bs4 import BeautifulSoup
from PySide2.QtGui import *
from PySide2.QtCore import *
from PySide2.QtWebKitWidgets import *
from PySide2.QtWidgets import QApplication
class dynamic_render(QWebPage):
def __init__(self, url):
self.frame = None
self.app = QApplication(sys.argv)
QWebPage.__init__(self)
self.loadFinished.connect(self._loadFinished)
self.mainFrame().load(QUrl(url))
QTimer.singleShot(0, self.sendKbdEvent)
QTimer.singleShot(100, app.quit)
self.app.exec_()
def _loadFinished(self, result):
self.frame = self.mainFrame()
self.app.quit()
self.app = None
Below, scaping code using pyside2:
I don't know how can i fix it?
Best regards.
Thanks.
Check if already an instance of QApplication is present or not as the error occurs when an instance is already running and you are trying to create a new one.
Write this in your main function:
if not QtWidgets.QApplication.instance():
app = QtWidgets.QApplication(sys.argv)
else:
app = QtWidgets.QApplication.instance()
For my pyside2 unit test the following worked fairly well
import PySide2
import unittest
class Test_qapplication(unittest.TestCase):
def setUp(self):
super(Test_qapplication, self).setUp()
if isinstance(PySide2.QtGui.qApp, type(None)):
self.app = PySide2.QtWidgets.QApplication([])
else:
self.app = PySide2.QtGui.qApp
def tearDown(self):
del self.app
return super(Test_qapplication, self).tearDown()
it was loosely based on stack overflow : unit-and-functional-testing-a-pyside-based-application