I'm new in pyqt. I want to do an application with a Qmainwindow with its menubar and menu items. when I click in some menu item A QMdiSubWindow should appear into the qmdiarea, How can I do that?
this is my qmainwindow code:
class Ui_mainForm(QMainWindow):
def __init__(self):
QtGui.QMainWindow.__init__(self)
self.resize(928, 695)
self.qareaMdi = QtGui.QWidget(self)
#all the design code...
self.actionFriends.triggered.connect(self.actionFriends_click)
#more code...
def actionFriends_click(self):
#how can I call a qmdisubwindow here?
and this is my QMdiSubWindow code:
class Ui_friendForm(QMdiSubWindow):
def __init__(self):
QtGui.QMdiSubWindow.__init__(self)
self.resize(878, 551)
QtCore.QMetaObject.connectSlotsByName(self)
thanks in advance
Update:
I modified the actionFriends_click function like this:
def actionFriends_click(self):
subwindow_friend = Ui_friendForm()
self.mdiArea.addSubWindow(subwindow_friend)
subwindow_friend.show()
Update 2:
I forgot It. We have to add a reference into Ui_mainForm
from VIEW.friendsForm import Ui_friendForm
In this case the QMdiSubWindows Ui_friendForm class is in the VIEW package.
We have to add a reference into Ui_mainForm (In this case the QMdiSubWindows Ui_friendForm class is in the VIEW package.) and I modified the actionFriends_click function like this:
from VIEW.friendsForm import Ui_friendForm
def actionFriends_click(self):
subwindow_friend = Ui_friendForm()
self.mdiArea.addSubWindow(subwindow_friend)
subwindow_friend.show()
Related
I am fairly new to object-oriented programming. I have a class called MessageWindow which generates a Tkinter text widget inside of a Frame. In my main function I want to write a message into the text widget but when I run the program I get: Class MessageWindow has no attribute text1
I've tried following other responses here on Stack overflow, and another tutorial on the web and I always end up back at the same error
from Tkinter import *
class MessageWindow(Frame):
def __init__(self, master):
Frame.__init__(self, master)
self.pack(fill='both', expand='yes')
self.text1 =Text(self,height=9, width=13)
self.text1.pack()
def main():
root=Tk()
root.title("MessageWindow")
app = MessageWindow(root)
root.mainloop()
MessageWindow.text1.insert(END,"This is a test Message")
MessageWindow.text1.pack()
if __name__=='__main__':
main()
Any help would be appreciated. I need to understand this for a larger GUI project that I am working on.
Ok so
1. You are referring to MessageWindow as your class object when you should be referring to app, as you have instantiated the class as 'app' in your main definition.
2. Your root.mainloop() should be after all your GUI code as it will not take affect if it is after/outisde the mainloop.
So this is the How the code is supposed to be:
from Tkinter import *
class MessageWindow(Frame):
def __init__(self, master):
Frame.__init__(self, master)
self.pack(fill='both', expand='yes')
self.text1 = Text(self,height=9, width=13)
self.text1.pack()
def main():
root=Tk()
root.title("MessageWindow")
app = MessageWindow(root)
# Fix one
app.text1.insert(END,"This is a test Message")
app.text1.pack()
# Fix two
root.mainloop()
if __name__=='__main__':
main()
Here is my setup. This isn't all the code, just the important parts
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolbar
class MyToolbar(NavigationToolbar):
def __init__(self, figure_canvas, parent, main):
self.toolitems = (
('Home', 'Reset Original View', 'home', 'home'), # (Title, Tooltip, Icon, callback function)
('Back', 'Back to previous view', 'back', 'back'),
('Forward', 'Forward to next view', 'forward', 'forward'),
('Clear', 'Clear all graphs', 'clearIcon', 'on_click_clear_graph'),
)
NavigationToolbar.__init__(self, figure_canvas, parent)
def on_click_clear_graph(self):
# I need to access calling class' (PlotWindow's) clearAx method here
super(MyToolbar,self).clearAx() # but this doesn't work
class PlotWindow():
def __init__(self):
self.figure = Figure()
self.ax = self.figure.add_subplot(111)
self.canvas = FigureCanvas(self.figure)
self.toolbar = MyToolbar(self.canvas, self, parent)
def clearAX(self):
self.ax.clear()
I use the MyToolbar class to add extra tools to the Matplotlib toolbar, but I also need to get access to the variables in the PlotWindow class.
I have been using super() in other parts of the program and I can use it to get access to parent classes but in this case I cannot seem to get it to work.
Am I missing some part of it?
Perhaps if the above code doesn't make sense this example below could be used.
class A(SomeOtherInheritedClass):
# how can I call print_something from class B here
# without interfering with SomeOtherInheritedClass
class B():
a = A()
def print_something(self):
print "something"
If you make a custom control as a subclass of wx.PyControl, the tab traversal will behave oddly. For example, with the code below, pressing tab a few times will get you stuck inside MyControl. Once you tab to a "Child of MyControl" textbox, you can only tab between the 2 "Child of MyControl" textboxes, and will never tab back to "Child of Panel".
class MyFrame(wx.Frame):
def __init__(self):
super(MyFrame, self).__init__(None)
panel = wx.Panel(self)
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(wx.TextCtrl(panel, value="Child of Panel"), flag=wx.EXPAND)
sizer.AddSpacer(30)
sizer.Add(MyControl(panel), flag=wx.EXPAND)
panel.SetSizer(sizer)
class MyControl(wx.PyControl):
def __init__(self, parent):
super(MyControl, self).__init__(parent, style=wx.BORDER_NONE|wx.TAB_TRAVERSAL)
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(wx.TextCtrl(self, value="Child of MyControl"), flag=wx.EXPAND)
sizer.AddSpacer(10)
sizer.Add(wx.TextCtrl(self, value="Child of MyControl"), flag=wx.EXPAND)
self.SetSizer(sizer)
Fixing the tab traversal to behave in a standard way is surprisingly simple. All you have to do is make your custom control subclass wx.Panel instead of wx.PyControl.
class MyControl(wx.Panel):
def __init__(self, parent):
super(MyControl, self).__init__(parent)
...
I am trying to get my save button to call a function from another class. I would like to click on the save button as much as I want and it should print "hello people" every time. Though, I am having trouble in getting the save button to work.
import tkinter as tk
from tkinter import filedialog
class Application(tk.Frame):
def __init__(self, parent):
tk.Frame.__init__(self, parent)
self.parent = parent
self.pack()
self.createWidgets()
def createWidgets(self):
#save button
self.saveLabel = tk.Label(self.parent, text="Save File", padx=10, pady=10)
self.saveLabel.pack()
#When I click the button save, I would like it to call the test function in the documentMaker class
self.saveButton = tk.Button(self.parent, text = "Save", command = documentMaker.test(self))
self.saveButton.pack()
class documentMaker():
def test(self):
print ("hello people")
root = tk.Tk()
app = Application(root)
app.master.title('Sample application')
object = documentMaker()
object.test()
app.mainloop()
In your documentMaker class, change the test method to a #staticmethod:
class documentMaker():
#staticmethod
def test(cls):
print ("hello people")
Then your saveButton's command can be:
command = documentMaker.test
A staticmethod is bound to the class, not to an instance of the class like an instance method. So, we can call it from the class's name directly. If you did not want it to be a staticmethod, you could keep it an instance method and have the command line change to:
command = documentMaker().test
I have the custom item delegate set for one column for QTableView. In some cases I need to remove it (i.e. set default item delegate). But it seems that QT does not allow this. The old delegate is used even after setting the new one.
According to QT documentation for QItemDelegate all handling should be done in the same delegate, but this may bring to performance issues. Is there any way to remove/reset to default the item delegate for QTableView.
I tried it in PyQt5 (sorry, im not able to write C++). I could set the standard itemGelegate to the view and then set a custom itemDelegate to one column. By using the „clicked“-signal i could replace the custom delegate by the standard itemDelegate for this column and vice versa.
This is my code, perhaps it helps:
import sys
from PyQt5 import QtGui, QtCore, QtWidgets
class MyDelegate(QtWidgets.QStyledItemDelegate):
def __init__(self):
QtWidgets.QStyledItemDelegate.__init__(self)
self.AlignmentFlag = QtCore.Qt.AlignHCenter | QtCore.Qt.AlignVCenter
self.abstand = 2
def paint(self, painter, item, index):
rahmen = item.rect.adjusted(self.abstand, self.abstand, -self.abstand, -self.abstand)
eintrag = index.data()
painter.save()
painter.drawText(rahmen,self.AlignmentFlag, eintrag)
painter.restore()
class MyModel(QtCore.QAbstractTableModel):
def __init__(self,):
QtCore.QAbstractTableModel.__init__(self)
self.items = [['a0','a1','a2','a3','a4'],['b0','b1','b2','b3','b4'],['c0','c1','c2','c3','c4']]
def columnCount(self,items):
cc = len(self.items[0])
return cc
def rowCount(self,items):
rc = len(self.items)
return rc
def data(self, index, role=2):
return self.items[index.row()][index.column()]
class MyWidget(QtWidgets.QTableView):
def __init__(self):
QtWidgets.QTableView.__init__(self)
self.setModel(MyModel())
self.setGeometry(200,200,530,120)
self.delegate_1 = MyDelegate()
self.delegate_2 = QtWidgets.QStyledItemDelegate()
self.setItemDelegate(self.delegate_2)
self.setItemDelegateForColumn(0,self.delegate_1)
self.clicked.connect(self.changeDelegate)
def changeDelegate(self,index):
if index.column() == 0:
delegate_new = self.delegate_2 if self.itemDelegateForColumn(index.column()) == self.delegate_1 else self.delegate_1
self.setItemDelegateForColumn(index.column(),delegate_new)
else:
pass
app = QtWidgets.QApplication(sys.argv)
widget = MyWidget()
widget.show()
sys.exit(app.exec_())