Variables in custom python module - python

I am making my own custom python module called zoro, and I want to enable people making a variable, and the variable is equal to a function in my module, but how do I make that?
I've already tried looking in to the code of other modules like turtle, and turtle used the self argument, so I tried to use that, but it said TypeError: win() missing 1 required positional argument: 'self'.
Code of my program to test the module:
import zoro
test = zoro.win("test","black",500,500)
test.zoro.winTitle("test2")
Code of my module:
from tkinter import *
def win(title,bg,w,h):
root = Tk()
root.title(title)
root.config(bg=bg)
root.geometry(str(w) + "x" + str(h))
return root
def winTitle(title):
root.title(title)
I want to do like:
test = zoro.win("test","black",500,500)
test.zoro.winTitle("test2")

Question:
What you want to do is called inheritance.
For example:
zoro.py
import tkinter as tk
class App(tk.Tk):
def __init__(self, title, bg, width, height):
super().__init__()
self.title(title)
self.geometry('{}x{}'format(width, height)
self.config(bg=bg)
Usage
import zoro
class MyApp(zoro.App):
def __init__(self):
super().__init__("test","black",500,500)
# Change title
self.title('my new title')
# Add further widgets
if __name__ == '__main__':
MyApp().mainloop()

Assuming you want your driver to work with the module as currently defined, you need a global variable named root for winTitle to use. In addition, the object returned by win doesn't have an attribute named zoro.
import zoro
zoro.root = zoro.win("test", "black", 500, 500)
zoro.winTitle("test2")
That said, your module should be fixed to avoid global variables in the first place.
from tkinter import *
def win(title, bg, w, h):
root = Tk()
root.title(title)
root.config(bg=bg)
root.geometry(str(w) + "x" + str(h))
return root
def winTitle(root, title):
root.title(title)
Then your driver will look like
import zoro
test = zoro.win("test", "black", 500, 500)
zoro.winTitle(test, "test2")

Related

Tkinter bind event isn't calling function

I have this code:
from tkinter import *
class logic():
def createComponent(self, event):
print("{0},{1}".format(event.x,event.y))
class gui(logic):
window = Tk()
obj = logic()
def initGui(self):
gui.window.mainloop()
def onClick(self):
gui.window.bind("<Button-1>",gui.obj.createComponent)
obj2 = gui()
obj2.initGui()
while True:
obj2.onClick()
In theory this code should print mouse coordinates on lmb click but "createComponent" isn't called for some reason (also no errors). What Im doing wrong?
Fixed the code:
window.mainloop() is already a loop putting it in while True breaks the code
The classes were setup wrong
from tkinter import *
window = Tk()
def createComponent(event):
print("{0},{1}".format(event.x,event.y))
window.bind("<Button-1>", createComponent)
window.mainloop()
OOP:
from tkinter import *
class windFuncs:
def createComponent(event):
print("{0},{1}".format(event.x,event.y))
class wind(Tk):
pass
window = wind()
window.bind("<Button-1>", windFuncs.createComponent)
window.mainloop()
You may wish to put createComponent in class wind

How to solve Error: image "pyimage1" doesn't exist

I wanted to program a simple graphical version of Tic Tac Toe in Python after having previously made a text based one with a friend. For this I used tkinter. I have been able to get rid of all mistakes in the first window where you choose which symbol you want. But in the second window when you are supposed to place it, when I press one of the buttons it tells me that "pyimage2" doesn't exist which seems to be a common error
I have already checked out some other threads where I was told that I should use TopLevel instead, since there can only be one instance of Tk(). But I already am using it, and when I try using two instances by using destroy() on the first, the error remains. I have also switched from simple PhotoImage to PIL, but even that is of no help
from tkinter import *
from random import *
from PIL import Image, ImageTk
global root
global SpielerSymbol
SpielerSymbol = "Defaultshit"
def combine_funcs(*funcs):
def combined_func(*args, **kwargs):
for f in funcs:
f(*args, **kwargs)
class SelectionScreen:
def __init__(self,pRoot):
Imageo = Image.open("o.png")
o = ImageTk.PhotoImage(Imageo)
Imagex = Image.open("x.png")
x = ImageTk.PhotoImage(Imagex)
Screen = Toplevel(pRoot)
self.TextField = Label(Screen, text="Please choose a symbol.")
self.TextField.grid(row=1,column=1)
self.ButtonX = self.SelectionButton(x,Screen)
self.ButtonX.Choice.grid(row = 2, column = 1)
self.ButtonO = self.SelectionButton(o,Screen)
self.ButtonO.Choice.grid(row = 2, column = 2)
Screen.mainloop()
class SelectionButton:
def __init__(self, pImage, pScreen):
self.Choice = Button(pScreen, image = pImage, command = lambda: combine_funcs(setSpielerSymbol(str(pImage)), pScreen.destroy(), pScreen.quit()))
def setSpielerSymbol(pZeichen):
global SpielerSymbol
SpielerSymbol = pZeichen
class Game:
def __init__(self, pRoot):
global SpielerSymbol
ImageFeldx = Image.open("Feldx.png")
Feldx = ImageTk.PhotoImage(ImageFeldx)
ImageFeldo = Image.open("Feldo.png")
Feldo = ImageTk.PhotoImage(ImageFeldo)
ImageFeld = Image.open("Feld.png")
Feld = ImageTk.PhotoImage(ImageFeld)
Window = Toplevel(pRoot)
Feld1 = [self.Feld(Feld,Window,1,1), self.Feld(Feld,Window,1,2), self.Feld(Feld,Window,1,3),
self.Feld(Feld,Window,2,1), self.Feld(Feld,Window,2,2), self.Feld(Feld,Window,2,3),
self.Feld(Feld,Window,3,1), self.Feld(Feld,Window,3,2), self.Feld(Feld,Window,3,3)]
Window.mainloop()
class Feld:
def __init__(self, pImage, pWindow, pRow, pColumn):
self.Feld1 = Button(pWindow, image = pImage, command =lambda: combine_funcs(self.setFeldImage(self), Window.quit()) )
self.Feld1.grid(row=pRow,column=pColumn)
def setFeldImage(self, pFeld1):
pFeld1.Feld1.config(image=SpielerSymbol)
def main():
root = Tk()
root.withdraw()
SelectionScreen1 = SelectionScreen(root)
print("Das ist das Werk von Feiglingen")
Game1 = Game(root)
main()
The output should be two windows, first the one where you choose a symbol, that one should work fine, and the second should be a tic tac toe field where clicking on a button should display the symbol you've chosen. And what I instead get is the error message image "pyimage1" doesn't exist
Also sorry for the ugly code, I am still a beginner, especially at Python

How to get a value from another file function? python

Does anyone can help here?
I have two files called game.py and settings.py, I just want to get one value from settings to use in game, but I dont know what I am doing wrong.
the value I want it is in the function bbbbb...
THIS IS MY SETTINGS
from tkinter import*
import game
class Application(Frame):
def __init__ (self, master):
Frame.__init__(self,master)
self.grid()
self.create_widgets()
def bbbbb(self):
self.xr = self.ball_numbers.get()
print("printing...", self.xr)
return self.xr
def create_widgets(self):
self.ball_numbers = IntVar()
Label(self,text = "Select how many balls you wish to play:").grid()
Radiobutton(self, text = "1 Ball", variable = self.ball_numbers, value = 1, command = self.bbbbb).grid ()
Radiobutton(self, text = "2 Balls", variable = self.ball_numbers, value = 2, command = self.bbbbb).grid ()
Radiobutton(self, text = "3 Balls", variable = self.ball_numbers, value = 3, command = self.bbbbb).grid ()
settings_window = Tk()
settings_window.title(" THE BOUNCER - Settings")
settings_window.geometry("600x600")
app = Application(settings_window)
settings_window.mainloop()
I need that value in the class handling_settings, in the function create_ball_numbers
AND THIS IS MY game.py
from livewires import games, color
from tkinter import*
import settings
import random
games.init(screen_width = 735, screen_height = 350, fps = 35)
class Bounce(games.Sprite):
def update(self):
if self.right > games.screen.width or self.left < 0:
self.dx = -self.dx
if self.top < 0:
self.dy = -self.dy
if self.bottom == 315 and self.overlapping_sprites:
self.dy = -self.dy
class Bar_moving(games.Sprite):
def update(self):
self.x = games.mouse.x
self.y = 315
class handling_settings():
self.yr = bbbbb()
print("printing number from settings ", self.yr)
def create_ball_numbers(self):
print("inside def", self.yr)
def main():
background = games.load_image("BG.jpg", transparent = False)
games.screen.background = background
call = handling_settings()
call.create_ball_numbers()
bar_small = games.load_image("bar_small.jpg", transparent = False)
the_bar_small = Bar_moving(image = bar_small, x = games.mouse.x)
games.screen.add(the_bar_small)
games.mouse.is_visible = False
games.screen.event_grab = True
games.screen.mainloop()
main()
I think I am not using on the right way IMPORT on top of the file.... keeping appearing this msg...
File "C:\Users\Bruno\Desktop\DIT\Object Oriented Programming\GAME - Assignment\game.py", line 3, in <module>
from settings import bbbbb
ImportError: cannot import name bbbbb
If I run both files individually... its ok... but when I try to get the value in bbbbb function in settings, I get stuck...
You have a circular import; settings imports game, which imports settings. At that time, neither module is fully done initializing (anything beyond the import lines has not yet run).
You don't actually use the game module in settings, so just remove the import game line from settings.py.
In game.py, you imported the settings name; bbbbb is an attribute on the Application class in that module. The line:
self.yr = bbbbb()
will never work here.
You should definitely not create a new Tk() root window in settings, however; you can only ever have one main loop in a Tk application. Make settings a dialog window triggered by the main application in game.
So to get the bbbbb() result, you need to instead spawn the settings dialog box, let the user interact with it, and then retrieve the ball_numbers setting when the user closes the dialog again.
First don't do any circular import, in settings.py there is no need to import game module.
As bbbbb is a function of class Application, therefore it cannot be called directly, to call it we need an object of the same class, which is already created as
app = Application(settings_window)
so, in module game.py, just use app object to call bbbbb()
self.yr = settings.app.bbbbb()

Class-calling function not working

I am trying to modify this piece of code by calling out a import window then follow by this code.
As I am also going to use the current piece of code (which is not written by me), the way it works is that when user selects one of the 3 prefixes ['a','b','c'], it will change the naming of the items in Maya accordingly.
Part of the former Coding (prefix window):
import maya.cmds as cmds
import maya.mel as mel
import pymel.core as pm
from PyQt4 import QtGui, QtCore
import sys, os
class createUI(QtGui.QFrame):
def __init__(self, parent=None):
QtGui.QFrame.__init__(self, parent)
self.shot = SHOT
self.initUI()
self.connections()
class MainWindow(QtGui.QWidget):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.resize(400,100)
self.move(300,300)
self.setWindowTitle('Select the prefix of rexPass')
self.pubDock = createUI()
vLayout = QtGui.QVBoxLayout()
vLayout.addWidget(self.pubDock)
self.setLayout(vLayout)
self.createConnection()
def createConnection(self):
self.connect( self.pubDock.cancelButton, QtCore.SIGNAL( "clicked()" ), self.close )
self.connect( self.pubDock.OKButton, QtCore.SIGNAL( "clicked()" ), self.close )
def setupRenderGlobals():
cmds.setAttr ('StartRange.multiFrame', 1)
cmds.setAttr ('EndRange.endFrame', 200)
cmds.setAttr ('WidthRes.xres', 1920)
cmds.setAttr ('HeightRes.yres', 1080)
def main():
setupRenderGlobals()
global app
app=QtGui.qApp
global form
form = MainWindow()
form.show()
Currently I would like to add on a function where it calls a selection window to import something, and once the selection is done, it will then calls out the above code.
The problem I have is where when user hits the import button in the import window, it automatically closes, and the perfix window is not showing up, or I would have the 2 windows showing up or just the prefix window and not the import window
My Coding:
class Processing():
'In-house code to call out the import window and they will have the name of 'prItems_a01''
importItems = procureItems.api.importItem()
allItems = pm.ls(type="prItems")
if allItem < 2 :
test = MainWindow()
else:
print ('testing')
Any advices?
The problem is here:
if allItem < 2 :
test = MainWindow()
else:
print ('testing')
allItems = pm.ls(type="prItems")
if allItem < 2 :
test = MainWindow()
pymel.core.ls returns a list, while 2 is an int. Python may not do what you expect here. From the docs:
Objects of different types except numbers are ordered by their type names; objects of the same types that don’t support proper comparison are ordered by their address.
So, "list" > "int"
What you probably meant to do is check the len of allItem, like this:
def processing():
# ~~ your code ~~ #
if len(allItem) < 2:
test = MainWindow()
else:
print ('testing')

Namespaces and Accessing Tkinter

I have a question, though I'm not sure what language to use. I'm a little confused about how to access the canvas defined in the main driver module from other modules without using globals. For instance, I have instantiated the canvas in driver.py, but am trying to draw from Level.py. For context, it is eventually going to read a text file and draw a map based on the data it extracts from it for an RPG-ish game. Here is my code:
Driver.py:
import tkinter
import Level
HEIGHT = 1024
WIDTH = 800
TILE_SIZE = 32
VERTICAL_TILES = HEIGHT//TILE_SIZE
HORIZONTAL_TILES = WIDTH//TILE_SIZE
root = tkinter.Tk()
root.title("RPG Land")
window = tkinter.Canvas(root,width= WIDTH, height=HEIGHT )
lev = Level.LevelMgr()
lev.loadLevel()
lev.drawLevel()
window.pack()
root.mainloop()
Annnd Level.py:
import tkinter
from driver import window
class LevelMgr:
def __init__(self):
self.levelData = []
self.visibleLevel = []
self.tileColors = {
0 : 'empty',
1 : 'wall',
2 : 'bush' }
def loadLevel(self):
fyle = open('levels/level1','r')
count = 0
for lyne in fyle:
self.levelData.append(lyne)
count += 1
def drawLevel(self):
currentY = 0
currentX = 0
for col in self.levelData:
currentY += 32
for t in col:
window.create_rectangle(currentX, currentY, 32, 32, fill="blue")
currentX += 32
Any advice on how to structure the program better would be also appreciated. When accessing other namespaces, what is the proper way to do so? Do I need to have "import Level" on driver.py, as well as "import driver" in Level.py? I'm a little confused as to the fundamental structure of such a program.
LevelMgr depends on window, so name it explicitly in __init__:
class LevelMgr:
def __init__(self, window):
self.window = window
def drawLevel(self):
...
for t in col:
self.window.create_rectangle(currentX, currentY, 32, 32, fill="blue")
Remove the import statement:
from driver import window
Then, in Driver.py:
lev = Level.LevelMgr(window)
Another possibility is to simply define window in Level.py instead of Driver.py.

Categories