Pyside/PyQT issues while adding a custom widget to main window - python-2.7

I have a working program that parses data from excel with Pandas. I tried several ways to display the output dataframe in a Qtextedit, but could never get the formatting to show up correctly. Long story short, I found a workaround online with a custom widget that works nicely. The problem I've run into is that the workaround example I found will display my data correctly in its own window, but I have not been able to figure out how to add the widget to my application. It seems to be an OOP issue. I'm learning, but cannot quite grasp what the problem is.
Below is the example widget that I have tried to add to my main application.
''' ps_QAbstractTableModel_solvents.py
use PySide's QTableView and QAbstractTableModel for tabular data
sort columns by clicking on the header title
here applied to solvents commonly used in Chemistry
PySide is the official LGPL-licensed version of PyQT
tested with PySide112 and Python27/Python33 by vegaseat 15feb2013
'''
import operator
from PySide.QtCore import *
from PySide.QtGui import *
class MyWindow(QWidget):
def __init__(self, data_list, header, *args):
QWidget.__init__(self, *args)
# setGeometry(x_pos, y_pos, width, height)
self.setGeometry(300, 200, 570, 450)
self.setWindowTitle("Widget Title.")
table_model = MyTableModel(self, data_list, header)
table_view = QTableView()
table_view.setModel(table_model)
# set font
font = QFont("Courier New", 14)
table_view.setFont(font)
# set column width to fit contents (set font first!)
table_view.resizeColumnsToContents()
# enable sorting
table_view.setSortingEnabled(True)
layout = QVBoxLayout(self)
layout.addWidget(table_view)
self.setLayout(layout)
class MyTableModel(QAbstractTableModel):
def __init__(self, parent, mylist, header, *args):
QAbstractTableModel.__init__(self, parent, *args)
self.mylist = mylist
self.header = header
def rowCount(self, parent):
return len(self.mylist)
def columnCount(self, parent):
return len(self.mylist[0])
def data(self, index, role):
if not index.isValid():
return None
elif role != Qt.DisplayRole:
return None
return self.mylist[index.row()][index.column()]
def headerData(self, col, orientation, role):
if orientation == Qt.Horizontal and role == Qt.DisplayRole:
return self.header[col]
return None
def sort(self, col, order):
"""sort table by given column number col"""
self.emit(SIGNAL("layoutAboutToBeChanged()"))
self.mylist = sorted(self.mylist,
key=operator.itemgetter(col))
if order == Qt.DescendingOrder:
self.mylist.reverse()
self.emit(SIGNAL("layoutChanged()"))
# the solvent data ...
header = ['Solvent Name', ' BP (deg C)', ' MP (deg C)', ' Density (g/ml)']
# use numbers for numeric data to sort properly
data_list = [
('ACETIC ACID', 117.9, 16.7, 1.049),
('ACETIC ANHYDRIDE', 140.1, -73.1, 1.087),
('ACETONE', 56.3, -94.7, 0.791),
('ACETONITRILE', 81.6, -43.8, 0.786),
('ANISOLE', 154.2, -37.0, 0.995),
('BENZYL ALCOHOL', 205.4, -15.3, 1.045),
('BENZYL BENZOATE', 323.5, 19.4, 1.112),
('BUTYL ALCOHOL NORMAL', 117.7, -88.6, 0.81),
('BUTYL ALCOHOL SEC', 99.6, -114.7, 0.805),
]
app = QApplication([])
win = MyWindow(data_list, header)
win.show()
app.exec_()
Below is what I have attempted while trying to add the widget to my PyQT application.
#from PySide.QtCore import *
import sys
from PySide import QtCore, QtGui
import operator
##############################THIS IS THE EXAMPLE###############
# from PySide.QtCore import *
# from PySide.QtGui import *
class MyWindow(QtGui.QWidget): #changed from QWidget to QtGui.QWidget because of import difference.
def __init__(self, data_list, header, *args):
QtGui.QWidget.__init__(self, *args) #added QtGui. to QWidget..
# setGeometry(x_pos, y_pos, width, height)
self.setGeometry(300, 200, 570, 450)
self.setWindowTitle("Widget Title.")
table_model = MyTableModel(self, data_list, header)
table_view = QtGui.QTableView() #Added QtGui. to QTableView..
table_view.setModel(table_model)
# set font
font = QtGui.QFont("Courier New", 14) #Added QtGui. to QFont..
table_view.setFont(font)
# set column width to fit contents (set font first!)
table_view.resizeColumnsToContents()
# enable sorting
table_view.setSortingEnabled(True)
layout = QtGui.QVBoxLayout(self) #Added QtGui. to QVBox..
layout.addWidget(table_view)
self.setLayout(layout)
class MyTableModel(QtCore.QAbstractTableModel): #changed from QAbstractTableModel to QtCore.QAbstractTableModel
def __init__(self, parent, mylist, header, *args):
QtCore.QAbstractTableModel.__init__(self, parent, *args) #changed from QAbstract to QtCore.QAbstract
self.mylist = mylist
self.header = header
def rowCount(self, parent):
return len(self.mylist)
def columnCount(self, parent):
return len(self.mylist[0])
def data(self, index, role):
if not index.isValid():
return None
elif role != QtCore.Qt.DisplayRole: #Added QtCore. to Qt.Display..
return None
return self.mylist[index.row()][index.column()]
def headerData(self, col, orientation, role):
if orientation == QtCore.Qt.Horizontal and role == QtCore.Qt.DisplayRole: #Added QtCore. to Qt.Horiz.. and Qt.Display..
return self.header[col]
return None
def sort(self, col, order):
"""sort table by given column number col"""
self.emit(QtCore.SIGNAL("layoutAboutToBeChanged()")) #Added QtCore. to SIGNAL..
self.mylist = sorted(self.mylist,
key=operator.itemgetter(col))
if order == QtCore.Qt.DescendingOrder: #added QtCore. to Qt.Descending...
self.mylist.reverse()
self.emit(QtCore.SIGNAL("layoutChanged()"))
# the solvent data ...
header = ['Solvent Name', ' BP (deg C)', ' MP (deg C)', ' Density (g/ml)']
# use numbers for numeric data to sort properly
data_list = [
('ACETIC ACID', 117.9, 16.7, 1.049),
('ACETIC ANHYDRIDE', 140.1, -73.1, 1.087),
('ACETONE', 56.3, -94.7, 0.791),
('ACETONITRILE', 81.6, -43.8, 0.786),
('ANISOLE', 154.2, -37.0, 0.995),
('BENZYL ALCOHOL', 205.4, -15.3, 1.045),
('BENZYL BENZOATE', 323.5, 19.4, 1.112),
('BUTYL ALCOHOL NORMAL', 117.7, -88.6, 0.81),
('BUTYL ALCOHOL SEC', 99.6, -114.7, 0.805),
]
# app = QApplication([])
# win = MyWindow(data_list, header)
# win.show()
# app.exec_()
###############################END EXAMPLE############################
######################THIS IS THE GUI FILE######################
class Ui_mainForm(object):
def setupUi(self, mainForm):
mainForm.setObjectName("mainForm")
mainForm.resize(1075, 643)
self.pushButton = QtGui.QPushButton(mainForm)
self.pushButton.setGeometry(QtCore.QRect(510, 40, 93, 31))
self.pushButton.setObjectName("pushButton")
self.lineEdit = QtGui.QLineEdit(mainForm)
self.lineEdit.setGeometry(QtCore.QRect(40, 40, 451, 31))
self.lineEdit.setObjectName("lineEdit")
self.lineEdit_2 = QtGui.QLineEdit(mainForm)
self.lineEdit_2.setGeometry(QtCore.QRect(40, 90, 451, 31))
self.lineEdit_2.setObjectName("lineEdit_2")
self.pushButton_2 = QtGui.QPushButton(mainForm)
self.pushButton_2.setGeometry(QtCore.QRect(510, 90, 93, 31))
self.pushButton_2.setObjectName("pushButton_2")
self.procButton = QtGui.QPushButton(mainForm)
self.procButton.setGeometry(QtCore.QRect(260, 130, 93, 28))
self.procButton.setObjectName("procButton")
self.placeholderWidget = QtGui.QWidget (MyWindow(data_list, header)) ############Trying to activate the custom class in gui.. was mainForm
self.placeholderWidget.setGeometry(QtCore.QRect(20, 179, 1011, 451))
self.placeholderWidget.setObjectName("placeholderWidget")
self.placeholderWidget.setAutoFillBackground(True)
self.retranslateUi(mainForm)
QtCore.QMetaObject.connectSlotsByName(mainForm)
def retranslateUi(self, mainForm):
mainForm.setWindowTitle(QtGui.QApplication.translate("mainForm", "Parser", None, QtGui.QApplication.UnicodeUTF8))
self.pushButton.setText(QtGui.QApplication.translate("mainForm", "Browse", None, QtGui.QApplication.UnicodeUTF8))
self.lineEdit.setPlaceholderText(QtGui.QApplication.translate("mainForm", "Select report", None, QtGui.QApplication.UnicodeUTF8))
self.lineEdit_2.setPlaceholderText(QtGui.QApplication.translate("mainForm", "Select log file", None, QtGui.QApplication.UnicodeUTF8))
self.pushButton_2.setText(QtGui.QApplication.translate("mainForm", "Browse", None, QtGui.QApplication.UnicodeUTF8))
self.procButton.setText(QtGui.QApplication.translate("mainForm", "Process files", None, QtGui.QApplication.UnicodeUTF8))
self.placeholderWidget.setToolTip(QtGui.QApplication.translate("mainForm", "THIS IS TOOLTIP", None, QtGui.QApplication.UnicodeUTF8))
###############THIS IS THE MAIN PROGRAM####################
class MainDialog(QtGui.QDialog, Ui_mainForm, MyWindow, MyTableModel): #Attempting to add custom widget to main window. getting error "Internal C++ object (PySide.QtGui.QWidget) already deleted."
def __init__(self, parent=None):
super(MainDialog, self).__init__(parent)
self.setupUi(self)
app = QtGui.QApplication(sys.argv) #Changed from QApplication to QtGui.QApplication because of different import method from seperate gui file.
mainForm = MainDialog()
mainForm.show()
# win = MyWindow(data_list, header) #These two lines display the custom example widget outside of the main window.
# win.show() #These two lines display the custom example widget outside of the main window.
app.exec_()
##########END MAIN PROGRAM##########
# app = QtGui.QApplication([]) #Added QtGui. to QApplication
# win = MyWindow(data_list, header) #Now to somehow add this to main window............
# win.show()
# app.exec_()
I have not been able make the custom widget appear in the main application. Additionally I am getting an error message at execution. Below is the full error message.
C:\Python27\python.exe C:/Users/Dirk/PycharmProjects/QwidgetTest_fromExample/Attempt-incorporate-example2.py
Traceback (most recent call last):
File "C:/Users/Dirk/PycharmProjects/QwidgetTest_fromExample/Attempt-incorporate-example2.py", line 143, in <module>
mainForm = MainDialog()
File "C:/Users/Dirk/PycharmProjects/QwidgetTest_fromExample/Attempt-incorporate-example2.py", line 139, in __init__
self.setupUi(self)
File "C:/Users/Dirk/PycharmProjects/QwidgetTest_fromExample/Attempt-incorporate-example2.py", line 116, in setupUi
self.placeholderWidget.setGeometry(QtCore.QRect(20, 179, 1011, 451))
RuntimeError: Internal C++ object (PySide.QtGui.QWidget) already deleted.
Process finished with exit code 1

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

How to destroy widget in GtK 3 python

I would like to complete the following code in order to destroy window when I click on widget to close window.
#!/usr/bin/env python
from gi.repository import Gtk, Gio
import sys
class MyWindow(Gtk.ApplicationWindow):
def __init__(self, app):
Gtk.Window.__init__(self, title="Menubutton Example", application=app)
self.set_default_size(600, 400)
grid = Gtk.Grid()
menubutton = Gtk.MenuButton()
menubutton.set_size_request(80, 35)
grid.attach(menubutton, 0, 0, 1, 1)
menumodel = Gio.Menu()
menubutton.set_menu_model(menumodel)
menumodel.append("New", "app.new")
menumodel.append("Quit", "app.quit")
self.add(grid)
class MyApplication(Gtk.Application):
def __init__(self):
Gtk.Application.__init__(self)
def do_activate(self):
win = MyWindow(self)
win.show_all()
def do_startup(self):
Gtk.Application.do_startup(self)
new_action = Gio.SimpleAction.new("new", None)
new_action.connect("activate", self.new_callback)
self.add_action(new_action)
quit_action = Gio.SimpleAction.new("quit", None)
quit_action.connect("activate", self.quit_callback)
self.add_action(quit_action)
def new_callback(self, action, parameter):
print("You clicked \"New\"")
def quit_callback(self, action, parameter):
print("You clicked \"Quit\"")
self.quit()
app = MyApplication()
exit_status = app.run(sys.argv)
sys.exit(exit_status)
In case any problem code is here
http://learngtk.org/tutorials/python_gtk3_tutorial/html/application.html
When I clicked on the left top of window to destroy it, it's block and after I have the message is : Do you want to force application to leave or expect any answer?

wxPython: Setting Value into Sheet in thread

I want to set value into sheet using thread.
import time
import wx
from wx.lib import sheet
from threading import Thread
EVT_RESULT_ID = wx.NewId()
def EVT_RESULT(win, func):
win.Connect(-1, -1, EVT_RESULT_ID, func)
class ResultEvent(wx.PyEvent):
def __init__(self, data):
wx.PyEvent.__init__(self)
self.SetEventType(EVT_RESULT_ID)
self.data = data
class TestThread(Thread):
def __init__(self, wxObject,sheet):
Thread.__init__(self)
self.wxObject = wxObject
self.sheet=sheet
self.start()
def run(self):
self.sheet.sheetload()
wx.PostEvent(self.wxObject, ResultEvent(self.sheet))
class MySheet(sheet.CSheet):
def __init__(self, parent):
sheet.CSheet.__init__(self, parent)
self.SetNumberRows(100)
self.SetNumberCols(30)
def sheetload(self):
self.SetNumberRows(200)
self.SetNumberCols(30)
self.EnableEditing(False)
for i in range(200):
for j in range(30):
self.SetCellValue(i,j,str(i))
class Newt(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None,-1, "Tutorial")
self.box = wx.BoxSizer(wx.VERTICAL)
toolbar2 = wx.ToolBar(self, wx.TB_HORIZONTAL | wx.TB_TEXT,size = (1000, 40))
self.show_btn =wx.Button(toolbar2, label="show")
self.show_btn.Enable(True)
self.Bind(wx.EVT_BUTTON, self.onShow,self.show_btn)
toolbar2.AddControl(self.show_btn)
self.box.Add((5,5) , 0)
self.box.Add(toolbar2)
self.box.Add((5,10) , 0)
toolbar2.Realize()
self.notebook = wx.Notebook(self, -1, style=wx.RIGHT)
self.box.Add(self.notebook, 1, wx.EXPAND)
self.Maximize(True)
self.SetSizer(self.box)
EVT_RESULT(self, self.updateDisplay)
def onShow(self, event):
sheet=MySheet(self.notebook)
TestThread(self,sheet)
def updateDisplay(self, msg):
t = msg.data
self.notebook.AddPage(t,"Logs")
app = wx.PySimpleApp()
frame = Newt().Show()
app.MainLoop()
Here I am using sheetload function defined in Mysheet to execute in TestThread. So i can set value into sheet in background without blocking main gui.
But i am getting this error, and my gui is crashing.
(python2.7:10775): GLib-CRITICAL **: Source ID 559 was not found when attempting to remove it
can you help me, what is wrong with this code.

Tkinter Instance has no attributes

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.

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)