How to set background color in Kivy - python-2.7

from kivy.app import App
from kivy.graphics import Color, Rectangle
from kivy.uix.button import Button
from kivy.uix.gridlayout import GridLayout
from kivy.uix.label import Label
from kivy.uix.screenmanager import ScreenManager, Screen, FadeTransition
#from kivy.config import Config
#Config.set('graphics','fullscreen','auto')
sm = ScreenManager(transition=FadeTransition())
class myGridLayout(GridLayout):
pass
class secondScreen(GridLayout, Screen):
def __init__(self, **kwargs):
super(secondScreen, self).__init__(**kwargs)
self.cols=1
self.add_widget(Label(text='Second Screen'))
self.btn1 = Button(text='Home')
self.add_widget(self.btn1)
self.btn1.bind(on_release=self.page1Func)
def page1Func(self, *args):
self.manager.current = 'page1'
class HomeScreen(GridLayout, Screen):
def __init__(self, **kwargs):
super(HomeScreen, self).__init__(**kwargs)
with self.canvas:
Color(rgba=[1,0,0,1])
Rectangle(pos=self.pos, size=self.size)
self.cols=1
self.add_widget(Label(text='[color=ec6135]Carloman Systems[/color]',font_size=50, markup=True))
self.layout_name=myGridLayout(spacing=50,padding=[50 , 0 , 50 , -50])
self.add_widget(self.layout_name)
self.layout_name.cols=3
self.btn1=Button(background_normal='./image-dark.png',
background_down='./image.png')
self.layout_name.add_widget(self.btn1)
self.btn1.bind(on_release = self.page2Func)
self.btn2=Button(background_normal='./image.png',
background_down='./image-dark.png')
self.layout_name.add_widget(self.btn2)
self.btn3=Button(background_normal='./image.png',
background_down='./image-dark.png')
self.layout_name.add_widget(self.btn3)
self.names_panel=myGridLayout()
self.add_widget(self.names_panel)
self.names_panel.cols=3
self.names_panel.add_widget(Label(text='btn1', font_size=30))
self.names_panel.add_widget(Label(text='btn2', font_size=30))
self.names_panel.add_widget(Label(text='btn3', font_size=30))
def page2Func(self, *args):
self.manager.current = 'page2'
#self.popup = Popup(title='Test popup', content=Label(text='Hello world'), auto_dismiss=False)
sm.add_widget(HomeScreen(name='page1'))
sm.add_widget(secondScreen(name='page2'))
sm.current='page1'
class MainScreen(App):
def build(self):
return sm
if __name__=='__main__':
MainScreen().run()
I am using this code for my GUI.
and i am using this code for background color.
Rectangle(pos=self.pos, size=self.size)
but it shows a small rectangle in bottom-left corner. it isn't in full screen.
i am new in kivy.
help me out guys, please. i want the rectangle that cover whole screen.

You need to bind pos and size so that every change will change the canvas drawing
... #inside __init__
def draw_background(widget, prop):
with widget.canvas:
Color(rgba=[1,0,0,1])
Rectangle(pos=self.pos, size=self.size)
self.bind(size=draw_background)
self.bind(pos=draw_background)
...

Related

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:

Replacing a figure on Tkinter Python

I am using Tkinter and would like to have the option to clear my graph and draw a new one in its place. I'm not sure what to put in my callback to do this. The best I can do so far is to replace the graph with a white box. The new graph is drawn underneath (which isn't ideal) and also appears as a blank white box for some reason. Apologies for asking such a basic question but I'm new to python and couldn't find an example using subplots on here.
import matplotlib
matplotlib.use("TkAgg")
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg
from matplotlib.figure import Figure
import Tkinter as tk
from Tkinter import *
import ttk
class Helmholtz_App(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
tk.Tk.wm_title(self, "Helmholtz Coils Data")
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 (PageOne,PageTwo):
frame = F(container, self)
self.frames[F] = frame
frame.grid(row=0, column=0, sticky="nsew")
self.show_frame(PageOne)
def show_frame(self, cont):
frame = self.frames[cont]
frame.tkraise()
class PageOne(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
fig1 = Figure(figsize=(5,5), dpi=100)
a = fig1.add_subplot(111)
def callback():
volt=[[0,1,2,3,4],[0,1,2,3,4]]
a.plot(volt[1],volt[0],'bo')
canvas = FigureCanvasTkAgg(fig1, self)
canvas.show()
canvas.get_tk_widget().pack(side=tk.BOTTOM, fill=tk.BOTH, expand=True)
toolbar = NavigationToolbar2TkAgg(canvas, self)
toolbar.update()
canvas._tkcanvas.pack(side=tk.TOP, fill=tk.BOTH, expand=True)
def ClearCallback():
#problem line
#~~~~~~~~~~~
fig1.clf()
# ~~~~~~~~~~
clearbutton.destroy()
clearbutton=ttk.Button(self, text="Clear", command=ClearCallback)
clearbutton.pack()
b=ttk.Button(self, text="Plot Data", command=callback)
b.pack()
class PageTwo(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
app = Helmholtz_App()
app.mainloop()
The code is based on this tutorial 1
I want the code to work so the "take data" button creates a graph, and the "clear" button removes that graph. Then when the "take data" button is pressed again it will put a new graph in the same place with none of the data from the old graph present.
Here is the

Should I be passing GUI-entered variables between classes or restructuring program?

The user enters values using line edits on the MyWidget screen and then presses the Enter button. This opens the MyDialog screen on which data will be plotted when the Run button is pressed. How can I make the line edit data accessible to run in MyDialog for plotting? Or, is there a better way of doing this which wouldn't require passing variables between classes? My program is based on this answer.
from PyQt4 import QtCore, QtGui, uic
# Import Qt widgets
from matplotlib.backends.backend_qt4agg \
import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt4agg \
import NavigationToolbar2QT as NavigationToolbar
from matplotlib.figure import Figure
GUI_FILE = "Minimal_UI.ui" # GUI with line edit and 'enter' button
form_class = uic.loadUiType(GUI_FILE)[0]
class MyWidget(QtGui.QWidget, form_class):
def __init__(self, parent=None):
super(MyWidget, self).__init__(parent)
self.setupUi(self)
self.pushButton_Enter.clicked.connect(self.on_pushButton_clicked)
self.dialogTextBrowser = MyDialog(self)
#QtCore.pyqtSlot()
def on_pushButton_clicked(self):
# I'd like to be able to pass Temp_0 to the run method
self.Temp_0 = self.lineEdit_Temp_0.text()
self.dialogTextBrowser.exec_()
class MyDialog(QtGui.QDialog):
def __init__(self, parent=None):
super(MyDialog, self).__init__(parent)
self.fig = Figure()
self.canvas = FigureCanvas(self.fig)
self.toolbar = NavigationToolbar(self.canvas, self)
self.run_button = QtGui.QPushButton('Run')
self.run_button.clicked.connect(self.run)
self.stop_button = QtGui.QPushButton('Stop')
self.stop_button.clicked.connect(self.stop)
layout = QtGui.QVBoxLayout()
# Widgets are stacked in the order they are added
layout.addWidget(self.toolbar)
layout.addWidget(self.canvas)
layout.addWidget(self.run_button)
layout.addWidget(self.stop_button)
self.setLayout(layout)
def run(self):
# Create axes
ax = self.fig.add_subplot(111)
# Discard the old graphs
ax.hold(False)
# Plot data--I'd like to be able to use line edit data here
ax.plot([1, 2, 3, 4], '*-')
# Refresh canvas
self.canvas.draw()
def stop(self):
print 'Stop Pressed'
if __name__ == "__main__":
import sys
app = QtGui.QApplication(sys.argv)
app.setApplicationName('MyWidget')
main = MyWidget()
main.show()
sys.exit(app.exec_())
MyDialog constructor has an attribute parent.
With the code bellow, you create an instance of MyDialog with MyWidget as a parent:
self.dialogTextBrowser = MyDialog(self)
Two ways for a widget to access data from it's parent:
Use the parent attribute in the __init__ function
self.lineEditData=parent.lineEdit.text()
Use the parent() method anywhere
def run(self):
self.lineEditData=self.parent().lineEdit.text()
I say it depends on how your suppose to use the application. If your suppose to fill the lineEdit once click and get a plot, I would use the parent attribute or directly pass the data in the __init__ function.
But if the user can go back to the lineEdit, change something, and click "run" again, then you should use the parent() method in run.

How to move from one class to another in kivy

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.

Mouse events in PyQt5 and PyQt4

I used to have an application in PyQt5, where user could move QGroupBox widget, by pressing mouse button and simply move it. In PyQt5 it works perfectly, but I had to refuse PyQt5 for some reasons and use PyQt4 instead of it. But now I can move my QgroupBox widget only after double click. I use the same piece of code, but in PyQt5 it worked after one click and now only after second one (after first click the whole application's window starts to move). What should I add/edit in order to reach the same result like in PyQt5?
from PyQt4.QtGui import *
from PyQt4.QtCore import *
class WidgetPattern(QGroupBox):
def __init__(self, name, parent=None):
super(WidgetPattern, self).__init__(parent=parent)
self.layout = QVBoxLayout(self)
self._offset = 0
self.widgetLength = 280
self.name = QLabel(parent=self)
self.name.setText(name)
self.name.adjustSize()
self.name.move(self.widgetLength / 2 - self.name.width() / 2, 5)
self.close_button = QToolButton(parent=self)
self.close_button.resize(24, 24)
self.close_button.setAutoRaise(True)
self.close_button.move(self.widgetLength - self.close_button.width(), 0)
self.close_button.setIcon(QIcon.fromTheme("application-exit"))
self.setFixedSize(280, 60)
def mousePressEvent(self, event):
self._offset = event.pos()
def mouseMoveEvent(self, event):
self.move(
QGroupBox.mapToParent(
self,
event.pos() -
self._offset))
class ConcertGUI(QWidget):
def __init__(self, parent=None):
super(ConcertGUI, self).__init__(parent)
widget=WidgetPattern("test")
self._main_layout = QVBoxLayout()
self._main_layout.addWidget(widget, 0)
self.setLayout(self._main_layout)
self.resize(1024, 500)
if __name__ == '__main__':
import sys
app = QApplication(sys.argv)
gui = ConcertGUI()
gui.show()
sys.exit(app.exec_())