How to move from one class to another in kivy - python-2.7

I am trying to make an android application...I am trying to switch from menu to server or client according to user input...but i am not able to switch from one class to another...main thing which pissed me off is that print statement inside ServerScreen is working but other part is not working...don't know why
Code:---
import kivy
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.uix.screenmanager import ScreenManager, Screen
class MenuScreen(Screen):
def __init__(self, **kwargs):
super(MenuScreen, self).__init__(**kwargs)
def Server(instance):
self.clear_widgets()
self.add_widget(Label ( text = 'Inside server function'))
server = ServerScreen()
#return server
#server.function()
self.add_widget(Label ( text = 'What Type Of Service You Want...???'))
button1 = Button(text = 'Server',size_hint = (None,None),pos = (0,0))
self.add_widget(button1)
button1.bind(on_press = Server)
button2 = Button(text = 'Client',size_hint = (None,None),pos = (100,0))
self.add_widget(button2)
#button2.bind(on_press = Client)
class ServerScreen(Screen):
def __init__(self, **kwargs):
super(ServerScreen, self).__init__(**kwargs)
print('Inside server screen')
self.clear_widgets()
self.add_widget(Label (text = 'Working As A Server'))
print("Hellooooooooooo")
sm = ScreenManager()
sm.add_widget(MenuScreen(name='Menu'))
sm.add_widget(ServerScreen(name='Server'))
#sm.add_widget(ClientScreen(name='Client'))
class FileApp(App):
def build(self):
#return Menu()
return sm
if __name__ == '__main__':
FileApp().run()
In which part i am making mistake...please point out that part & provide how can i solve that...
Output--->
Inside server screen
Hellooooooooooo

Look at my solution inspired by this excellent comment from inclement : Kivy: Changing screens in screen manager with an on_press event
import kivy
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.uix.label import Label
from kivy.uix.button import Button
from kivy.uix.screenmanager import ScreenManager, Screen
class MenuScreen(Screen):
def switching_function(*args):
global sm
sm.current = 'Server'
def __init__(self, **kwargs):
super(MenuScreen, self).__init__(**kwargs)
# def Server(instance):
# self.clear_widgets()
# self.add_widget(Label ( text = 'Inside server function'))
# server = ServerScreen()
# #return server
# #server.function()
self.add_widget(Label ( text = 'What Type Of Service You Want...???'))
button1 = Button(text = 'Server',size_hint = (None,None),pos = (0,0))
self.add_widget(button1)
# button1.bind(on_press = Server)
button1.bind(on_press = self.switching_function)
button2 = Button(text = 'Client',size_hint = (None,None),pos = (100,0))
self.add_widget(button2)
#button2.bind(on_press = Client)
class ServerScreen(Screen):
def __init__(self, **kwargs):
super(ServerScreen, self).__init__(**kwargs)
print('Inside server screen')
self.clear_widgets()
self.add_widget(Label (text = 'Working As A Server'))
print("Hellooooooooooo")
sm = ScreenManager()
sm.add_widget(MenuScreen(name='Menu'))
sm.add_widget(ServerScreen(name='Server'))
#sm.add_widget(ClientScreen(name='Client'))
class FileApp(App):
def build(self):
#return Menu()
return sm
The problem is with server = ServerScreen() inside
def Server(instance):
self.clear_widgets()
self.add_widget(Label ( text = 'Inside server function'))
server = ServerScreen()
#return server
#server.function()
It creates a new ServerScreen, not the ServerScreen which is actually displayed at the moment (so
Inside server screen
Hellooooooooooo
is displayed, but the ScreenManager has no idea that this additional Screen is existing.

Related

How to get the item in list view using with enter key

In my program i want to use key press event in list view.When i press the enter key then only my selected text will print..Can any one please tell me how to use key press event for list view.I tried with installEventFilter but this method showing non type error.
Given below is my code:
import sys
from PyQt4 import QtCore,QtGui
class List_View(QtGui.QMainWindow):
def __init__(self, parent=None):
super(List_View, self).__init__(parent)
self.listview = QtGui.QListView()
model = QtGui.QStandardItemModel(self.listview)
for i in ['linux', 'windows', 'mac os']:
model.appendRow(QtGui.QStandardItem(i))
self.listview.setModel(model)
self.listview.entered.connect(self.add_items)
widget = QtGui.QWidget()
self.setCentralWidget(widget)
vlay = QtGui.QVBoxLayout(widget)
vlay.addWidget(self.listview)
self.resize(400, 200)
def add_items(self):
pass #here i need to print particular item in list view
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
w = List_View()
w.show()
sys.exit(app.exec_())
I think you have not read the docs of the entered signal or you have not understood it, that signal only triggers when the mouse is on the item but for this you must activate the mouse tracking with self.listview.setMouseTracking(True)
A simple solution is to use a QShortcut:
import sys
from PyQt4 import QtCore,QtGui
class List_View(QtGui.QMainWindow):
def __init__(self, parent=None):
super(List_View, self).__init__(parent)
shorcut = QtGui.QShortcut(
QtGui.QKeySequence(QtCore.Qt.Key_Return),
self
)
shorcut.activated.connect(self.on_enter_pressed)
self.listview = QtGui.QListView()
model = QtGui.QStandardItemModel(self.listview)
for i in ['linux', 'windows', 'mac os']:
model.appendRow(QtGui.QStandardItem(i))
self.listview.setModel(model)
widget = QtGui.QWidget()
self.setCentralWidget(widget)
vlay = QtGui.QVBoxLayout(widget)
vlay.addWidget(self.listview)
self.resize(400, 200)
#QtCore.pyqtSlot()
def on_enter_pressed(self):
print("enter press")
ix = self.listview.selectionModel().currentIndex()
print(ix.data())
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
w = List_View()
w.show()
sys.exit(app.exec_())

Python Tkinter- method for printing not working after being called from another script

I have a class called app.py within that class there's a method called print_raw_records_screen here's the part of the class and the method
app.py
#!/usr/bin/python
# -*- coding: utf-8 -*-
from Tkinter import *
from ttk import *
import os
import mftsession
class Example(Frame):
def __init__(self, parent):
Frame.__init__(self, parent)
self.parent = parent
self.filename = ""
self.initUI()
#defining a function that that receives the raw records from the mftsession.py and print it to the screen
#this script will be called by the mftsession.py in
#process_mftfile()
def print_raw_records_screen(self,records):
self.area.delete(1.0, "end")
self.area.insert('1.0',records)
def initUI(self):
self.parent.title("Mtf Analyzer")
#initializing and configuring menubar
menubar = Menu(self.parent)
self.parent.config(menu=menubar)
fileMenu = Menu(menubar)
fileMenu.add_command(label="Open file", command=self.fileOpen)
fileMenu.add_command(label="Exit", command=self.onExit)
menubar.add_cascade(label="File", menu=fileMenu)
#specify grid row and column spaces
self.pack(fill=BOTH, expand=True)
self.columnconfigure(1, weight=1)
self.columnconfigure(3, pad=7)
self.rowconfigure(3, weight=1)
self.rowconfigure(5, pad=7)
lbl = Label(self, text="File Name")
lbl.grid(row=1, column=0, sticky=W, pady=4, padx=5)
self.filename_area = Entry(self)
self.filename_area.grid(row=1, column=1, columnspan=5, padx=5, sticky=E+W+S+N)
analize_button = Button(self, text="Analize", command=self.processFile)
analize_button.grid(row=1, column=6, padx=5)
self.area = Text(self)
self.area.grid(row=2, column=1, columnspan=2, rowspan=4,
padx=5, sticky=E+W+S+N)
#configure the raw output view
def onExit(self):
self.quit()
#this function selects and opens the file to analize
def fileOpen(self):
from tkFileDialog import askopenfilename
Tk().withdraw()
self.filename = askopenfilename()
#populate the filename field
self.set( self.filename)
#do the processing of the file obtained. Populate the file NAME entry or
#send the filename to the analyzeMFT.py
def processFile(self):
arguments = "analyzeMFT.py -f "+self.filename+" -d --bodyfull -l -o "+self.filename+".csv"
os.system(arguments)
mftsession.MftSession.process_mft_file(self)
#get and set methods for the entry field
def get(self):
return self.filename_area.get()
def set(self, value):
self.filename_area.delete(0, END)
self.filename_area.insert(0,value)
def main():
root = Tk()
root.geometry("450x350+500+500")
app = Example(root)
root.mainloop()
if __name__ == '__main__':
main()
This method is called by another external script like this
mftsession.py
import csv
import json
import os
import sys
from optparse import OptionParser
import mft
import app
from Tkinter import *
from ttk import *
class MftSession:
"""Class to describe an entire MFT processing session"""
#staticmethod
def fmt_excel(date_str):
return '="{}"'.format(date_str)
#staticmethod
def fmt_norm(date_str):
return date_str
def __init__(self):
self.mft = {}
self.fullmft = {}
self.folders = {}
self.debug = False
self.mftsize = 0
def process_mft_file(self):
root = Tk()
appi = app.Example(root)
self.sizecheck()
self.build_filepaths()
# reset the file reading
self.num_records = 0
self.file_mft.seek(0)
raw_record = self.file_mft.read(1024)
if self.options.output is not None:
self.file_csv.writerow(mft.mft_to_csv(None, True, self.options))
while raw_record != "":
record = mft.parse_record(raw_record, self.options)
if self.options.debug:
print record
appi.print_raw_records_screen(raw_record ) #THIS FUNCTION WHILE INVOKED THIS WAY IS NOT WORKING
..........
The script analyzeMFT.py called by the app.py through the subrouting
#!/usr/bin/python
import sys
from os import path
def main():
session = mftsession.MftSession()
session.mft_options()
session.open_files()
session.process_mft_file()
if __name__ == '__main__':
if __package__ is None:
sys.path.append( path.dirname( path.dirname( path.abspath(__file__) ) ) )
import mftsession
main()
else:
import mftsession
main()
When called this way it prints nothing to the window, but when i invoke it for testing within its own class it prints the test
def print_raw_records_screen(self,records):
self.area.delete(1.0, "end")
self.area.insert('1.0', records)
and invoke like print_raw_records_screen("any test"): in the app.py
An image can tell alot. and summarize
What am i doing wrong? I sense it's the instantiation am doing wrong. I need diretions please
From what I can see here you have a few issues causing problems.
you are importing app.py on mftsession.py instead importing mftsession.py on app.py.
You are trying to use appi.print_raw_records_screen(raw_record) on a completely different instance of the Example() class with appi = app.Example(root) remove that part all together.
It is bad practice to importing inside a function. Import at the start of each py file.
There is so many things going on in your code I had to create a Minimal, Complete, and Verifiable example example of my own to illustrate the relation between files.
Here is a simple example of how the 2 files can interact and the way I think you are trying to do things.
Here I have created a main file called app.py:
from Tkinter import *
# You might need to import the py file with the package name as well.
# Change the package name to the package your python files are located in.
import PACKAGE_NAME.file_b
class Example(Frame):
def __init__(self, parent):
Frame.__init__(self, parent)
self.parent = parent
self.filename = ""
analize_button = Button(self.parent, text="Analize", command=self.processFile)
analize_button.pack()
self.area = Text(self.parent, height = 2, width = 40)
self.area.pack()
def print_raw_records_screen(self,records):
self.area.delete(1.0, "end")
self.area.insert('1.0',records)
def processFile(self):
PACKAGE_NAME.file_b.process_mft_file(self)
if __name__ == "__main__":
root = Tk()
app = Example(root)
root.mainloop()
Here I have created a file called file_b.py
from Tkinter import *
def process_mft_file(self):
record = "Some values assigned to a variable"
self.print_raw_records_screen(record)
The results look something like this:

SIGNALs are not working in PySide

I wrote a simple application in Python and PySide. When I run it, SIGNALs are not working.
The application starts without errors.
from PySide.QtCore import *
from PySide.QtGui import *
import sys
class Form(QDialog):
def __init__(self, parent=None):
super(Form, self).__init__(parent)
dial = QDial()
dial.setNotchesVisible(True)
spinbox = QSpinBox()
layout = QHBoxLayout()
layout.addWidget(dial)
layout.addWidget(spinbox)
self.setLayout(layout)
self.connect(dial, SIGNAL("valueChaged(int)"), spinbox.setValue)
self.connect(spinbox, SIGNAL("valueChaged(int)"), dial.setValue)
self.setWindowTitle("Signals and Slots")
# END def __init__
# END class Form
def main():
app = QApplication(sys.argv)
form = Form()
form.show()
app.exec_()
# END def main
if __name__ == '__main__':
main()
# END if
I am using:
Pyside 1.2.2;
Python 2.7.6;
OS Centos; Windows 7
I am running the application with:
Sublime Text 3 and Eclipse Luna;
How can I make SIGNALs working?
Your signal name is incorrect;
Incorrect :
valueChaged (int)
Correct :
valueChanged (int)
Test it, work fine;
import sys
from PyQt4.QtGui import *
from PyQt4.QtCore import *
class QFormDialog (QDialog):
def __init__(self, parent = None):
super(QFormDialog, self).__init__(parent)
self.myQial = QDial()
self.myQSpinbox = QSpinBox()
self.myQHBoxLayout = QHBoxLayout()
self.myQial.setNotchesVisible(True)
self.myQHBoxLayout.addWidget(self.myQial)
self.myQHBoxLayout.addWidget(self.myQSpinbox)
self.setLayout(self.myQHBoxLayout)
self.connect(self.myQial, SIGNAL('valueChanged(int)'), self.myQSpinbox.setValue)
self.connect(self.myQSpinbox, SIGNAL('valueChanged(int)'), self.myQial.setValue)
self.setWindowTitle('Signals and Slots')
if __name__ == '__main__':
myQApplication = QApplication(sys.argv)
myQFormDialog = QFormDialog()
myQFormDialog.show()
myQApplication.exec_()
Note : PyQt4 & PySide is same way to implemented.

Passing an SQLAlchemy Session to a TKinter controller

I am currently learning how to work with the tkinter gui and I am trying to integrate with SQLAlchemy. The first hurdle was figuring out how to move between frames without destroying/closing the window, luckily I found this question: Switch between two frames in tkinter. So I used a lot of the provided code and created a simple application that is trying to have someone log in.
Now for the part I can't figure out. I have a function _check_credentials(self) deep inside the structure of windows that is trying to query the db. I have successfully created the table and queried it elsewhere.
I need to pass the session from the main.py module to the Login class and finally to the _check_credentials(self) method.
main.py -> Authorzation() -> Login() -> login_btn = tk.Button() -> _check_credentials()
Additional info:
I have included all of my code. Right now it runs, but crashes when the login button is pressed.
I have attempted to pass the session directly, ie. Authorzation(Session) but that crashes immediately.
Also, I am trying to follow the guidelines laid out in the sqlalchemy docs http://docs.sqlalchemy.org/en/latest/orm/session.html, FAQ, "When do I construct a Session, when do I commit it, and when do I close it?".
main.py:
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
from module1 import Authorzation
import Tkinter as tk
Base = declarative_base()
engine = create_engine('sqlite:///:memory:', echo=True)
Base.metadata.create_all(engine)
Session = sessionmaker(bind=engine)
session = Session()
app = Authorzation()
app.mainloop()
module1.py:
import Tkinter as tk
import user
TITLE_FONT = ("Helvetica", 18, "bold")
class Authorzation(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
# the container is where we'll stack a bunch of frames
# on top of each other, then the one we want visible
# will be raised above the others
container = tk.Frame(self)
container.pack(side="top", fill="both", expand=True)
container.grid_rowconfigure(0, weight=1)
container.grid_columnconfigure(0, weight=1)
self.frames = {}
for F in (Login, Register):
frame = F(container, self)
self.frames[F] = frame
# put all of the pages in the same location;
# the one on the top of the stacking order
# will be the one that is visible.
frame.grid(row=0, column=0, sticky="nsew")
self.show_frame(Login)
def show_frame(self, c):
'''Show a frame for the given class'''
frame = self.frames[c]
frame.tkraise()
class Login(tk.Frame):
def __init__(self, parent, controller):
self.controller = controller
tk.Frame.__init__(self, parent)
label = tk.Label(self, text="Title", font=TITLE_FONT)
label.pack(side="top", fill="x", pady=10)
#Create the Username field
label_username = tk.Label(self, text="username")
label_username.pack()
self.username = tk.StringVar()
tk.Entry(self, textvariable=self.username).pack()
#Create the password field
label_password = tk.Label(self, text="password")
label_password.pack()
self.password = tk.StringVar()
tk.Entry(self, textvariable=self.password).pack()
login_btn = tk.Button(self, text="Login",
command=self._check_credentials)
login_btn.pack(pady=5)
reg_btn = tk.Button(self, text="Registration",
command=lambda: controller.show_frame(Register))
reg_btn.pack(pady=10)
def _check_credentials(self):
session_user = session.query(user.User)\
.filter_by(
username=self.username
).first()
if session_user:
return session_user.check_pwd(), session_user
else:
print("Sorry we could not find your username")
return False, None
self.controller.show_frame(Login)
class Register(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
label = tk.Label(self, text="This is page 1", font=TITLE_FONT)
label.pack(side="top", fill="x", pady=10)
button = tk.Button(self, text="Go to the start page",
command=lambda: controller.show_frame(Login))
button.pack()
After doing research on *args, and **kwargs. I realized I had not tried putting the session first in the __init__() function. Here is how I then passed the session to the controller.
main.py:
app = Authorzation(session)
module1.py
class Authorzation(tk.Tk):
def __init__(self, session, *args, **kwargs):
self.session = session
Once the session was in the controller it was easy to reference it from the Login() frame.
module1.py:
class Login(tk.Frame):
def __init__(self, parent, controller):
self.controller = controller
...
def _check_credentials(self):
session = self.controller.session
Note: this solution is also nice because it alleviates the need to pass the session through the button.

Tkinter widgets not appearing

I was testing an app I was writing but I just get a blank window and no widgets.
from Tkinter import*
class App(Frame):
def _init_(self, master):
frame = Frame(master)
frane.pack()
self.instruction = Label(frame, text = 'Password:')
self.instruction.pack()
self.button = Button(frame, text = 'Enter', command = self.reveal)
self.button.pack()
root = Tk()
root.title('Password')
root.geometry('350x250')
App(root)
root.mainloop()
You have a couple of typos. The first is in the name of the constructor method:
def _init_(self, master):
Should read:
def __init__(self, master):
Note the double underscore - see the docs for Python objects.
The second is inside your constructor:
frane.pack()
You're also missing a declaration for a method named 'reveal' in your App class:
self.button = Button(frame, text="Enter", command=self.reveal)
The working example reads:
from Tkinter import *
class App(Frame):
def __init__(self, master):
Frame.__init__(self, master)
self.pack()
frame = Frame()
frame.pack()
self.instruction = Label(frame, text="Password:")
self.instruction.pack()
self.button = Button(frame, text="Enter", command=self.reveal)
self.button.pack()
def reveal(self):
# Do something.
pass
root = Tk()
root.title("Password")
root.geometry("350x250")
App(root)
root.mainloop()
See also: The Tkinter documentation.