from src.view import *
from src.view import View
from src.model import Model
from pubsub import pub
import tkinter
from tkinter import *
class Controller:
def __init__(self, model, view):
# Variables
self.model = Model(controller=self) #point to Model Object
self.view = View(controller=self) #point to view object
def uploadAction(self, audios):
for audio in audios:
path = os.path.split(audio)
audio = path[1]
self.view.add_audio(audio)
`Model file`
class Model:
def __init__(self, controller):
self.controller = controller
`View file`
class View:
def __init__(self, container, controller):
self.controller = controller
self.annotation_box = None
super().__init__(container)
self.setup()
# set the controller
# self.controller = None
def setup(self):
#this class will run first
#calling the methos to setup the user interface
self.create_menu()
self.create_panedwindow()
self.create_audio_frame()
self.create_transcript_frame()
self.create_annotation_frame()
self.setup_menu()
self.setup_panedwindow()
self.setup_audio_frame()
self.setup_transcript_frame()
self.setup_annotation_frame()
`Main file`
from tkinter import *
from src.view import View
from src.model import Model
from src.controller import Controller
if __name__ == '__main__':
main_window = Tk()
main_window.geometry('1400x800')
main_window.title("Interview Elicitation Tool")
# controller = Controller(main_window)
view = View(Controller)
model = Model(Controller)
controller = Controller(model, view)
main_window.mainloop()
`
I am getting
Traceback (most recent call last):
File "C:\Users\santh\PycharmProjects\pythonProject\MVC-IET\src\main.py", line 13, in
view = View(Controller)
TypeError: View.init() missing 1 required positional argument: 'controller'
I tried to add controller=self in main.py also it is not working.
i am new to python. I don't know what to do
Related
I am trying to make a tkinter desktop application (Notepad) using classes but I found an Attribute Error in my code. I made three files "menu_option.py", "textarea.py" and "window_frame.py". Run the "menu_option.py" file so that you found the error. I am using python (3.9). Also is there any another way to connect "new_file" function to menu item.
Here is my code below:
menu_option.py
from tkinter import *
from textarea import TextArea
from window_frame import Window
class Menu_Option(TextArea):
file = None
def __init__(self, master, newfile=None):
super().__init__(root)
self.Menubar = 'MenuBar'
self.Filemenu = 'FileMenu'
self.root = self.root
self.master = self.master
self.newfile = newfile
def launch(self):
self.Menubar = Menu(self.root)
self.Filemenu = Menu(master=self.Menubar, tearoff=0)
self.Filemenu.add_command(label='New File...', command=self.newfile)
self.Menubar.add_cascade(label='File', menu=self.Filemenu)
self.root.config(menu=self.Menubar)
class Features(Menu_Option):
def __init__(self, master):
super().__init__(master, newfile=self.new_file)
def new_file(self):
global file
self.root.title(self.title)
file = None
self.textarea.delete(1.0, END)
if __name__ == '__main__':
root = Tk()
Window(root).launch()
TextArea(root).launch()
Menu_Option(root).launch()
Features(root).launch()
root.mainloop()
textarea.py
from tkinter import *
from window_frame import Window
from tkinter.scrolledtext import ScrolledText
class TextArea(Window):
def __init__(self, name):
super().__init__(name)
self.name = self.root
self.master = 'root'
self.textarea = 'text_area'
self.font = 'courier 14 normal'
def launch(self):
self.textarea = ScrolledText(self.root, font=self.font)
self.textarea.pack(expand=True, fill=BOTH)
if __name__ == '__main__':
root = Tk()
Window(root).launch()
TextArea(root).launch()
root.mainloop()
window_frame.py
from tkinter import *
class Window:
def __init__(self, root):
self.root = root
self.geometry = '1000x550+100+100'
self.title = 'Untitled - ProBook'
def launch(self):
self.root.geometry(self.geometry)
self.root.title(self.title)
if __name__ == '__main__':
root = Tk()
Window(root).launch()
root.mainloop()
Error:
Exception in Tkinter callback
Traceback (most recent call last):
File "D:\Installed Programs\Python\lib\tkinter\__init__.py", line 1892, in __call__
return self.func(*args)
File "C:\Users\vaish\OneDrive\ProBook\menu_option.py", line 35, in new_file
self.textarea.delete(1.0, END)
AttributeError: 'str' object has no attribute 'delete'
Since Menu_Option() has override launch() function, therefore TextArea.launch() will not be executed and so instance variable textarea is still a string.
If child class wants to inherit parent class launch() functionality, you need to call the parent class launch() in its launch() function:
textarea.py
class TextArea(Window):
...
def launch(self):
super().launch() # call parent class launch()
self.textarea = ScrolledText(self.root, font=self.font)
self.textarea.pack(expand=True, fill=BOTH)
menu_option.py
class Menu_Option(TextArea):
...
def launch(self):
super().launch() # execute parent class launch()
...
...
if __name__ == "__main__":
root = Tk()
#Window(root).launch() # <- no need to execute
#TextArea(root).launch() # <- no need to execute
#Menu_Option(root).launch() # <- no need to execute
Features(root).launch()
root.mainloop()
Note that Window(root).launch(), TextArea(root).launch() and Menu_Option(root).launch() are not required.
You have initialized self.textarea="text_area" in textarea.py . But when you import it in menu_option.py, you are overwriting the function launch, which is supposed to set the value of self.textarea to a ScrolledText and pack it. To solve this you have to include the code in launch function of textarea.py in the function launch of Menu_Option class.
from tkinter import *
from tkinter.scrolledtext import ScrolledText
from textarea import TextArea
from window_frame import Window
class Menu_Option(TextArea):
file = None
def __init__(self, master, newfile=None):
super().__init__(root)
self.Menubar = 'MenuBar'
self.Filemenu = 'FileMenu'
self.root = self.root
self.master = self.master
self.newfile = newfile
def launch(self):
self.Menubar = Menu(self.root)
#You have to include these 2 lines of code which were overwritten
self.textarea = ScrolledText(self.root, font=self.font)
self.textarea.pack(expand=True, fill=BOTH)
self.Filemenu = Menu(master=self.Menubar, tearoff=0)
self.Filemenu.add_command(label='New File...', command=self.newfile)
self.Menubar.add_cascade(label='File', menu=self.Filemenu)
self.root.config(menu=self.Menubar)
I have two classes and am trying to inherit the class in one file from the class in another. However, my problem occurs when I try to put account_validation in another file, and inherit it in my PageTwo class. I am subject to the error:
Traceback (most recent call last):
File "C:\Users\stecd\Desktop\NEA - topLevel - client server\Frontend - Copy.py", line 1949, in <module>
customerEnd = selfService()
File "C:\Users\stecd\Desktop\NEA - topLevel - client server\Frontend - Copy.py", line 49, in __init__
self.frame = F(self.container, self)
File "C:\Users\stecd\Desktop\NEA - topLevel - client server\Frontend - Copy.py", line 91, in __init__
validation.account_validation.__init__(self)
TypeError: __init__() missing 2 required positional arguments: 'parent' and 'controller'
My code:
#Inheriting class from same file attempt
#file.py
class account_validation():
def __init__(self):
self.test = 'test2'
class PageTwo(tk.Frame,
validation.account_validation):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
account_validation.__init__(self)
print(self.test)
#inheriting class from another file
#validation.py
class account_validation():
def __init__(self):
self.test = 'test2'
#file.py
import validation
class PageTwo(tk.Frame, account_validation):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
account_validation.__init__(self)
print(self.test)
Inheriting from the same file.
import tkinter as tk
class account_validation:
def __init__(self):
self.test = 'test'
class PageTwo(tk.Frame, account_validation):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
account_validation.__init__(self)
print(self.test)
parent = tk.Tk()
page = PageTwo(parent, 'test')
parent.mainloop()
Inheriting from a different file. Assuming it's in the same path and under the name validation.py.
import tkinter as tk
from validation import account_validation
class PageTwo(tk.Frame, account_validation):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
account_validation.__init__(self)
print(self.test)
parent = tk.Tk()
page = PageTwo(parent, 'test')
parent.mainloop()
and in the file validation.py.
class account_validation:
def __init__(self):
self.test = 'test'
I'm trying to call an init method, and it's parents in a function. I'm probably doing something obviously dumb, but I can't figure it out. I get an error when I have this code:
from kivy.app import App
from kivy.uix.widget import Widget
from kivy.uix.button import Button
from kivy.properties import NumericProperty, ReferenceListProperty, ObjectProperty, ListProperty
from kivy.clock import Clock
from kivy.graphics import Color
class FieldCommand(Widget):
def __init__(self, **kwargs):
super(FieldCommand, self).__init__(**kwargs)
self.myBoard = Board(col=2, rows=2)
for c in range(4):
self.add_widget(Button(text = c))
class Board(Widget):
def __init__(self, **kwargs):
super(Board, self).__init__(**kwargs)
class FieldCommandApp(App):
def build(self):
return FieldCommand()
if __name__ == '__main__':
FieldCommandApp().run()
Specifically, my error reads:
File "/Users/.../PycharmProjects/FieldCommand/venv/lib/python3.7/site-packages/kivy/uix/widget.py", line 350, in __init__
super(Widget, self).__init__(**kwargs)
File "kivy/_event.pyx", line 243, in kivy._event.EventDispatcher.__init__
TypeError: object.__init__() takes exactly one argument (the instance to initialize
)
I was following the example here:
class Container(BoxLayout):
def __init__(self, **kwargs):
super(Container, self).__init__(**kwargs)
self.previous_text = open(self.kv_file).read()
parser = Parser(content=self.previous_text)
widget = Factory.get(parser.root.name)()
Builder._apply_rule(widget, parser.root, parser.root)
self.add_widget(widget)
Why is my application getting an error?
Your call to self.myBoard = Board(col=2, rows=2) includes kwargs for col and rows that are passed to the Widget __init__(), which does not accept those kwargs. So the fix is to extract those kwargs in your Board class. You can do that by simply adding Properties in your Board class like this:
class Board(Widget):
# default values for `row` and `cols`
col = NumericProperty(1)
rows = NumericProperty(1)
def __init__(self, **kwargs):
super(Board, self).__init__(**kwargs)
I have created a modelEditor in Maya using PyQt4 and code from internet, but I don't know how to close it when I run this script again. I've tried using sys.exit(app.exec_()) but that doesn't work.
# -*- coding: utf-8 -*-
from PyQt4 import QtCore, QtGui
import maya.cmds as cmds
import maya.OpenMayaUI as mui
import sip
import sys
global app
class MyDialog(QtGui.QDialog):
def __init__(self, parent, **kwargs):
super(MyDialog, self).__init__(parent, **kwargs)
self.setObjectName("MyWindow")
self.resize(800, 600)
self.setWindowTitle("PyQt ModelPanel Test")
self.verticalLayout = QtGui.QVBoxLayout(self)
self.verticalLayout.setObjectName("mainLayout")
layout = mui.MQtUtil.fullName(long(sip.unwrapinstance(self.verticalLayout)))
cmds.setParent(layout)
self._cameraName = cmds.camera()[0]
self.newEditor = cmds.modelEditor()
nodeName = cmds.modelEditor(self.newEditor,cam=self._cameraName,edit = True,hud = 0,alo = 0,pm = 1,da = "smoothShaded")
ptr = mui.MQtUtil.findControl(nodeName)
self.modelPanel = sip.wrapinstance(long(ptr), QtCore.QObject)
self.verticalLayout.addWidget(self.modelPanel)
def show(self):
super(MyDialog, self).show()
self.modelPanel.repaint()
def show():
if (cmds.window(MyDialog,ex = True)):
cmds.deleteUI(MyDialog)
global app
app = QtGui.QApplication.instance()
ptr = mui.MQtUtil.mainWindow()
win = sip.wrapinstance(long(ptr), QtCore.QObject)
d = MyDialog(win)
d.show()
Here's one way you can go about it.
Have a class singleton that will hold the class's instance. Then in the constructor you can check if an instance exists; if it does, then delete it and reset the variable.
# -*- coding: utf-8 -*-
from PyQt4 import QtCore, QtGui
import maya.cmds as cmds
import maya.OpenMayaUI as mui
import sip
import sys
global app
class MyDialog(QtGui.QDialog):
instance = None # This will contain an instance of this class.
def __init__(self, parent, **kwargs):
# Delete any existing instance, then set this as the current instance.
self.delete_instance()
self.__class__.instance = self
super(MyDialog, self).__init__(parent, **kwargs)
self.setObjectName("MyWindow")
self.resize(800, 600)
self.setWindowTitle("PyQt ModelPanel Test")
self.verticalLayout = QtGui.QVBoxLayout(self)
self.verticalLayout.setObjectName("mainLayout")
layout = mui.MQtUtil.fullName(long(sip.unwrapinstance(self.verticalLayout)))
cmds.setParent(layout)
self._cameraName = cmds.camera()[0]
self.newEditor = cmds.modelEditor()
nodeName = cmds.modelEditor(self.newEditor,cam=self._cameraName,edit = True,hud = 0,alo = 0,pm = 1,da = "smoothShaded")
ptr = mui.MQtUtil.findControl(nodeName)
self.modelPanel = sip.wrapinstance(long(ptr), QtCore.QObject)
self.verticalLayout.addWidget(self.modelPanel)
def delete_instance(self):
if self.__class__.instance is not None:
try:
self.__class__.instance.deleteLater()
except Exception as e:
pass
def show(self):
super(MyDialog, self).show()
self.modelPanel.repaint()
def show():
global app
app = QtGui.QApplication.instance()
ptr = mui.MQtUtil.mainWindow()
win = sip.wrapinstance(long(ptr), QtCore.QObject)
d = MyDialog(win)
d.show()
Do note that if you have an instance open and reload() the module, it won't delete the opened instance because the class will be different!
I am lost with all the parenting/initialising issues and have no idea why this does not work.
So I create a Label, then I create another Label with some painting in it, them I make a widget that contains the two, then I would like to put this new widget inside the main window... but nothing appears
import sys
import os
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
class Labhtml(QLabel):
def __init__(self):
super().__init__()
label = QLabel('html')
class Bar(QLabel):
def __init__(self):
super().__init__()
self.resize(100, 5)
def paintEvent(self, e):
qp = QPainter(self)
qp.setBrush(QColor(200, 0, 0))
qp.drawRect(0,0,200,3)
class Wid(QWidget):
def __init__(self, parent):
super().__init__(parent=parent)
widget = QWidget()
html = Labhtml()
bar = Bar()
self.layout = QVBoxLayout(widget)
self.layout.addWidget(html)
self.layout.addWidget(bar)
class Example(QScrollArea):
def __init__(self):
super().__init__()
widget = QWidget()
layout = QVBoxLayout(widget)
layout.addWidget(Wid(widget))
self.setWidget(widget)
self.setWidgetResizable(True)
self.show()
if __name__ == '__main__':
app = QApplication(sys.argv)
ex = Example()
sys.exit(app.exec_())
First for the class Labhtml, when you inherit from QLabel, you can use the methods and the attributes of the base class, or use the instantiation mechanism to pass some parameters :
class Labhtml(QLabel):
def __init__(self):
super().__init__()
self.setText('html')
Then you don't need to create another widget inside the Wid class, but you have to refer to self instead :
class Wid(QWidget):
def __init__(self, parent):
super().__init__(parent=parent)
html = Labhtml()
bar = Bar()
self.layout = QVBoxLayout(self)
self.layout.addWidget(html)
self.layout.addWidget(bar)
About the instantiation mechanism you could also write the classes by declaring a new text argument (the same used for the Qlabel), and pass it when you create your instance :
class Labhtml(QLabel):
def __init__(self, text):
super().__init__(text)
class Wid(QWidget):
def __init__(self, parent):
super().__init__(parent=parent)
html = Labhtml('html')