Tkinter Instance has no attributes - python-2.7

I am having an error against an innocent wish to play an audio in audio player using Tkinter. Error is:
Traceback (most recent call last):
File "C:\Users\Mudassar\workspace\Player\main_gui.py", line 43, in
<module>
app = GUI(playerobj)
File "C:\Users\Mudassar\workspace\Player\main_gui.py", line 10, in
__init__
self.create_button_frame()
AttributeError: GUI instance has no attribute 'create_button_frame'
My Code main_gui.py is:
from Tkinter import *
import tkFileDialog
import player
class GUI:
def __init__(self, player):
self.player = player
player.parent = player
self.root = Tk()
self.create_button_frame()
self.create_bottom_frame()
self.root.mainloop()
def create_button_frame(self):
buttonframe = Frame(self.root)
self.playicon = PhotoImage(file='../icons/play.gif')
self.stopicon = PhotoImage(file='../icons/stop.gif')
self.playbtn=Button(buttonframe, text ='play', image=self.playicon,
borderwidth=0, command=self.toggle_play_pause)
self.playbtn.image = self.playicon
self.playbtn.grid(row=3, column=3)
buttonframe.grid(row=1, pady=4, padx=5)
def create_bottom_frame(self):
bottomframe = Frame(self.root)
add_fileicon = PhotoImage(file='../icons/add_file.gif')
add_filebtn = Button(bottomframe, image=add_fileicon, borderwidth=0,
text='Add File', command = self.add_file)
add_filebtn.image = add_fileicon
add_filebtn.grid(row=2, column=1)
bottomframe.grid(row=2, sticky='w', padx=5)
def toggle_play_pause(self):
if self.playbtn['text'] == 'play':
self.playbtn.config(text='stop', image=self.stopicon)
self.player.start_play_thread()
elif self.playbtn['text'] == 'stop':
self.playbtn.config(text = 'play', image=self.playicon)
self.player.pause()
def add_file(self):
tfile = tkFileDialog.askopenfilename(filetypes = [('All supported',
'.mp3 .wav .ogg'), ('All files', '*.*')])
self.currentTrack = tfile
if __name__=='__main__':
playerobj = player.Player()
app = GUI(playerobj)
My Player button functions in another (as they have nothing to do with error)are:
import pyglet
from threading import Thread
class Player():
parent = None
def play_media(self):
try:
self.myplayer=pyglet.media.Player()
self.source = pyglet.media.load(self.parent.currentTrack)
self.myplayer.queue(self.source)
self.myplayer.queue(self.source)
self.myplayer.play()
pyglet.app.run()
except:
pass
def start_play_thread(self):
player_thread = Thread(target=self.play_media)
player_thread.start()
def pause(self):
try:
self.myplayer.pause()
self.paused = True
except: pass
Please help.

Seems like your problem is indentation. Your create_button_frame() function is not an attribute of the class GUI, it is a global function. Indent all the functions taking parameter self four spaces to the right. Then they will be methods of your class GUI.

Related

having issues with pyqtgraph in pyqt4

I have tried to boil down my program to be as simple as possible and still be functional. First is my UI file with the tabs that I want. It has a graph in the Control tab and I want the play button to start the plot.
When I start it I can't get the graph to show up. any help would be appreciated.
from PyQt4 import QtCore, QtGui
try:
_fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
def _fromUtf8(s):
return s
try:
_encoding = QtGui.QApplication.UnicodeUTF8
def _translate(context, text, disambig):
return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
def _translate(context, text, disambig):
return QtGui.QApplication.translate(context, text, disambig)
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName(_fromUtf8("MainWindow"))
MainWindow.resize(800, 600)
self.centralwidget = QtGui.QWidget(MainWindow)
self.centralwidget.setObjectName(_fromUtf8("centralwidget"))
self.tabWidget = QtGui.QTabWidget(self.centralwidget)
self.tabWidget.setGeometry(QtCore.QRect(0, 0, 801, 421))
self.tabWidget.setStyleSheet(_fromUtf8(""))
self.tabWidget.setObjectName(_fromUtf8("tabWidget"))
self.tab_4 = QtGui.QWidget()
self.tab_4.setObjectName(_fromUtf8("tab_4"))
self.tabWidget.addTab(self.tab_4, _fromUtf8(""))
self.tab_2 = QtGui.QWidget()
self.tab_2.setObjectName(_fromUtf8("tab_2"))
self.tabWidget.addTab(self.tab_2, _fromUtf8(""))
self.tab = QtGui.QWidget()
self.tab.setObjectName(_fromUtf8("tab"))
self.pushButton = QtGui.QPushButton(self.tab)
self.pushButton.setGeometry(QtCore.QRect(290, 340, 75, 31))
icon = QtGui.QIcon()
icon.addPixmap(QtGui.QPixmap(_fromUtf8("play_button.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.pushButton.setIcon(icon)
self.pushButton.setObjectName(_fromUtf8("pushButton"))
self.pushButton_2 = QtGui.QPushButton(self.tab)
self.pushButton_2.setGeometry(QtCore.QRect(460, 340, 75, 31))
icon1 = QtGui.QIcon()
icon1.addPixmap(QtGui.QPixmap(_fromUtf8("pause_button.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.pushButton_2.setIcon(icon1)
self.pushButton_2.setObjectName(_fromUtf8("pushButton_2"))
self.pushButton_3 = QtGui.QPushButton(self.tab)
self.pushButton_3.setGeometry(QtCore.QRect(630, 340, 75, 31))
icon2 = QtGui.QIcon()
icon2.addPixmap(QtGui.QPixmap(_fromUtf8("resume_button.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.pushButton_3.setIcon(icon2)
self.pushButton_3.setObjectName(_fromUtf8("pushButton_3"))
self.graphicsView = QtGui.QGraphicsView(self.tab)
self.graphicsView.setGeometry(QtCore.QRect(205, 1, 591, 341))
self.graphicsView.setObjectName(_fromUtf8("graphicsView"))
self.tabWidget.addTab(self.tab, _fromUtf8(""))
self.tab_3 = QtGui.QWidget()
self.tab_3.setObjectName(_fromUtf8("tab_3"))
self.tabWidget.addTab(self.tab_3, _fromUtf8(""))
MainWindow.setCentralWidget(self.centralwidget)
self.statusbar = QtGui.QStatusBar(MainWindow)
self.statusbar.setObjectName(_fromUtf8("statusbar"))
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
self.tabWidget.setCurrentIndex(2)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow", None))
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_4), _translate("MainWindow", "Calibration", None))
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_2), _translate("MainWindow", "Material", None))
self.pushButton.setText(_translate("MainWindow", "Start Plot", None))
self.pushButton_2.setText(_translate("MainWindow", "Pause", None))
self.pushButton_3.setText(_translate("MainWindow", "Resume", None))
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab), _translate("MainWindow", "Control", None))
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_3), _translate("MainWindow", "Operator", None))
if __name__ == "__main__":
import sys
app = QtGui.QApplication(sys.argv)
MainWindow = QtGui.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
The second is my graphing class which does work when I make a gui with code, but I would like to be able to plug it into a program with a ui file.
import sys
import time
import datetime
from PyQt4 import QtCore, QtGui, uic
from PyQt4.QtGui import *
from PyQt4.QtCore import *
import pyqtgraph as pg
import random
from workingraspitab2 import Ui_MainWindow
class Main(QMainWindow, Ui_MainWindow):
def __init__(self, parent=None):
super(Main, self).__init__(parent)
self.setupUi(self)
self.graphicsView = QtGui.QStackedWidget()
self.login_widget = LoginWidget(self)
self.graphicsView.addWidget(self.login_widget)
self.pushButton.clicked.connect(self.plotter)#the play button
self.curve = self.login_widget.it1
self.curve2 =self.login_widget.it2
def plotter(self):
self.data =[0]
self.data2 = [0]
self.timer = QtCore.QTimer()
self.timer.timeout.connect(self.updater)
self.timer.start(0)
print self.data
def updater(self):
self.data.append(self.data[-1]+10*(0.5-random.random()))
self.curve.setData(self.data, pen=pg.mkPen('b', width=1))
self.data2.append(self.data2[-1]+0.1*(0.5-random.random()))
self.curve2.setData(self.data2, pen=pg.mkPen('r', width=1))
print self.data
class LoginWidget(QtGui.QWidget):
def __init__(self, parent=None):
super(LoginWidget, self).__init__(parent)
pg.setConfigOption('background', 'w')
pg.setConfigOption('foreground', 'k')
self.plot = pg.PlotWidget(title='Force and Extension vs. Time')
p1 = self.plot.plotItem
p2 = pg.ViewBox()
p1.showAxis('right')
p1.scene().addItem(p2)
p1.getAxis('right').linkToView(p2)
p2.setXLink(p1)
self.plot.getAxis('bottom').setLabel('Time', units='s')
self.plot.getAxis('left').setLabel('Force', units='lbf', color="#0000ff")
p1.getAxis('right').setLabel('Extension', units='in.', color="#ff0000")
def updateViews():
p2.setGeometry(p1.vb.sceneBoundingRect())
p2.linkedViewChanged(p1.vb, p2.XAxis)
updateViews()
p1.vb.sigResized.connect(updateViews)
self.it1 = p1.plot()
self.it2 = pg.PlotCurveItem()
p2.addItem(self.it2)
if __name__ == '__main__':
import sys
app = QtGui.QApplication(sys.argv)
window = Main()
window.show()
sys.exit(app.exec_())
Had to put everything in the Main class to get it to work. I was hoping for a more elegant solution. I still cant get the background or foreground to change, but it is working and here is the code:
class Main(QMainWindow, Ui_MainWindow):
def __init__(self, parent=None):
super(Main, self).__init__(parent)
self.setupUi(self)
pv = self.graphicsView
pv.setTitle('Force and Extension vs. Time')
pg.setConfigOption('background', 'w')
pg.setConfigOption('foreground', 'k')
p1 = pv.plotItem
p2 = pg.ViewBox()
p1.showAxis('right')
p1.scene().addItem(p2)
p1.getAxis('right').linkToView(p2)
p2.setXLink(p1)
pv.getAxis('bottom').setLabel('Time', units='s')
pv.getAxis('left').setLabel('Force', units='lbf', color="#0000ff")
p1.getAxis('right').setLabel('Extension', units='in.', color="#ff0000")
def updateViews():
p2.setGeometry(p1.vb.sceneBoundingRect())
p2.linkedViewChanged(p1.vb, p2.XAxis)
updateViews()
p1.vb.sigResized.connect(updateViews)
self.it1 = p1.plot()
self.it2 = pg.PlotCurveItem()
p2.addItem(self.it2)
self.pushButton.clicked.connect(self.plotter)
self.pushButton_2.clicked.connect(lambda: self.timer.stop())
self.pushButton_3.clicked.connect(self.timer_start)
self.curve = self.it1
self.curve2 = self.it2

Python Tkinter: Update entry field from another class

I have a Python Tkinter GUI class as following:
import Tkinter as tk
class AppClient(tk.Frame):
def __init__(self, master):
error_class = ErrorClass()
self.val_error_code = error_class.error_message
tk.Frame.__init__(self, master)
self.pack()
##Frame for error message display
error_frame = tk.Frame(self, highlightbackground="violet", highlightcolor="violet", highlightthickness=1, width=600, height = 60, bd= 0)
error_frame.pack(padx = 10, pady = 5, anchor = 'w')
## error code: Label and Entry
tk.Label(error_frame, text = 'Error message').grid(row = 0, column = 0, sticky = 'w')
self.error_code = tk.Entry(error_frame, background = 'white', width = 27)
self.error_code.grid(row = 0, column = 1, sticky = 'w', padx = 5, pady = 5)
def update_error_messsage(self):
self.error_code.delete(0, 'end')
self.error_code.insert(0, self.val_error_code)
if __name__ == '__main__':
root = tk.Tk()
app_client = AppClient(root)
app_client.mainloop()
I want to update the entry field error_code dynamically by using the function update_error_message. The problem is, error message is continuously updated from another class ErrorClass() and I am receiving the error message to my AppClient class by variable error_message.
How can I update the error_code entry filed whenever the value of the variable error_message got updated in another class (ErrorClass())
The simple solution is that you need a reference to your instance of AppClient inside of ErrorClass, and then allow the instance of ErrorClass to pass the new value to the app
For example:
class AppClient(tk.Frame):
def __init__(self, master):
error_class = ErrorClass(self)
...
def update_error_messsage(self, error_code):
self.error_code.delete(0, 'end')
self.error_code.insert(0, error_code)
class ErrorClass():
def __init__(self, app):
self.app = app
def update_error(self):
...
error_code = 42
self.app.update_error_message(error_code)

Python, Tkinter, Can not access StringVar() Object

with the attached code i try to access the StringVar object in the widget object himself.
But unfortunately it says 'AttributeError: 'str' object has no attribute 'set''
Any idea why? Thanks in advance..
import Tkinter as tk
class mainWindow:
def __init__(self, master):
self.master = master
self.fieldList = {}
f = tk.Entry(self.master, text='', width = 7)
f.grid(column=0, row=0)
self.addToFieldList(f, 'MyFieldA')
def addToFieldList(self, fieldObj, fieldId):
fieldObj.bind('<Return>', lambda event, temp=fieldObj :self.commitField(event, temp))
t = tk.StringVar()
fieldObj['textvariable'] = t
setattr(fieldObj, 'fieldId', fieldId)
self.fieldList[fieldId] = fieldObj
def commitField(self, event, sender):
newValue = sender.get()
t = sender['textvariable']
t.set('newValue') # here comes the error
def main():
root = tk.Tk()
app = mainWindow(root)
root.wm_geometry("500x180")
root.mainloop()
if __name__ == '__main__':
main()
Put self in front of the StringVar which will let you call it without an error. This is because it is not a global variable and so the function cannot access it. Also change t = sender['textvariable'] to sender['textvariable'] = t.

python Attributes error

i just want to ask, what's wrong with my codes, or am i missing something. because when i call the function PausePlay() in the PlayAndPause() I always get an error saying:
self.dbusIfaceKey.Action(dbus.Int32("16"))
AttributeError: 'OpenOMX' object has no attribute 'dbusIfaceKey'
Here's the code:
OPTIONS = 'omxplayer -o local -t on --align center --win "0 0 {1} {2}" \"{0}\"'
from PyQt4 import QtCore, QtGui
from PyQt4.QtGui import *
from Tkinter import *
import sys
import os
from os import system
import dbus,time
from subprocess import Popen
try:
_fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
_fromUtf8 = lambda s: s
MoviePath = '/media/HP v250w/Our Story in 1 Minute.mp4'
class OpenOMX(QtCore.QThread):
def __init__(self):
QtCore.QThread.__init__(self)
def run(self):
global MoviePath
global myctr
width = QtGui.QApplication.desktop().width()
height = QtGui.QApplication.desktop().height()
cmd = OPTIONS.format(MoviePath,width,height-60)
Popen([cmd], shell=True)
done,retry = 0,0
while done==0:
try:
with open('/tmp/omxplayerdbus', 'r+') as f:
omxplayerdbus = f.read().strip()
bus = dbus.bus.BusConnection(self.omxplayerdbus)
print 'connected'
object = bus.get_object('org.mpris.MediaPlayer2.omxplayer','/org/mpris/MediaPlayer2', introspect=False)
self.dbusIfaceProp = dbus.Interface(object,'org.freedesktop.DBus.Properties')
self.dbusIfaceKey = dbus.Interface(object,'org.mpris.MediaPlayer2.Player')
done=1
except:
retry+=1
if retry >= 50:
print 'ERROR'
raise SystemExit
def PausePlay(self):
self.dbusIfaceKey.Action(dbus.Int32('16'))
class VidControls(QtGui.QMainWindow):
def __init__(self):
QtGui.QMainWindow.__init__(self)
def setupUi(self, MainWindow):
'some codes here'
def retranslateUi(self, MainWindow):
self.btnPause.clicked.connect(self.PlayAndPause)
def PlayAndPause(self):
self.opn = OpenOMX()
self.opn.PausePlay()
if __name__=='__main__':
app = QtGui.QApplication(sys.argv)
ex = VidControls()
ex.show()
play = OpenOMX()
play.start()
sys.exit(app.exec_())
Any Comments or Suggestions would be highly appreciated. Thanks.

call local variable of a function in another function

I have created a setting window in python where i have a few path settings which has to be one time setting.Here is the sample demo code,
import wx
import os
class SettingWindow(wx.Frame):
def __init__(self, parent, id, title):
wx.Frame.__init__(self, parent, id, title)
panel= wx.Panel(self,-1)
font = wx.Font(8, wx.DEFAULT, wx.NORMAL, wx.BOLD)
field1 = wx.TextCtrl(panel,pos=(120,25),size=(170,20))
vsizer = wx.BoxSizer(wx.VERTICAL)
field1_sz=wx.BoxSizer(wx.HORIZONTAL)
field2_sz=wx.BoxSizer(wx.HORIZONTAL)
field1_lbl=wx.StaticText(panel,-1, label='Repo URL path:', pos=(25, 25))
field1_lbl.SetFont(font)
field1_sz.AddSpacer(50)
field1_sz.Add(field1_lbl)
field1_sz.AddSpacer(5) # put 5px of space between
field1_sz.Add(field1)
field1_sz.AddSpacer(50)
vsizer.AddSpacer(50)
vsizer.Add(field1_sz)
vsizer.AddSpacer(15)
vsizer.Add(field2_sz)
vsizer.AddSpacer(50)
btn1 = wx.Button(panel, label='Browse',pos=(300,25),size=(60,20))
btn1.Bind(wx.EVT_BUTTON, self.opendir)
def opendir(self, event):
dlg = wx.DirDialog(self, "Choose a directory:", style=wx.DD_DEFAULT_STYLE | wx.DD_NEW_DIR_BUTTON)
if dlg.ShowModal() == wx.ID_OK:
field1.SetValue("%s",dlg.GetPath())
dlg.Destroy()
class MyApp(wx.App):
def OnInit(self):
frame= SettingWindow(None,-1,'Setting Window')
frame.Show()
self.SetTopWindow(frame)
return True
app= MyApp(0)
app.MainLoop()
I want to display the path which i get from opendir in textCtrl.I am finding an error like below,
Traceback (most recent call last):
File "D:\PROJECT\SettingWindow.py", line 58, in opendir
return (field1)
NameError: global name 'field1' is not defined
use self.field1 instead of variable field1:
self.field1 = wx.TextCtrl(panel,pos=(120,25),size=(170,20))
self.field1.SetValue(dlg.GetPath())
This code works to make the TextCtrl field hidden when clicked on the checkbox
def OnCheckBox(self,event):
if self.checkbox.Value==False:
self.field.Enable(True)
else:
self.field.Enable(False)