Menus and toolbar - python

I am new in programming and I have created a simple application with one class in Python and PySide which manipulates phone bill csv files. Now I want an option for mobile too.
How can I add a menubar, when my class inherits from QWidget? Should I write another class which inherits from QMainWindow and then make an instance of my first class as a central widget? Is this the right way to do this?
class MyWidget(QtGui.QWidget):
def __init__(self, parent=None):
super(MyWidget, self).__init__(parent)
....
class MyWindow(QtGui.QMainWindow):
def __init__(self, parent=None):
super(MyWindow, self).__init__(parent)
widget = MyWidget()
self.setCentralWidget(widget)
...

There's no need for a QMainWindow, you can simply create a QMenuBar in your widget.
class MyWidget(QtGui.QWidget):
def __init__(self, parent=None):
super(MyWidget, self).__init__(parent)
self.menu=QtGui.QMenuBar()
self.menu.addAction("do something")
layout=QtGui.QVBoxLayout()
layout.addWidget(self.menu)
A QMainWindow is basically a widget which already has a layout with a menu bar, a toolbar, a status bar, etc. If you don't need all of those functionality, you can use a simple QWidget and add only what you want.

Related

How to bind a function to an Action from Qt menubar?

I'm using Python3 and PyQt5, make my widgets and windows in Qt Designer. What is more, I do not generate .py files from a .ui. I simply load it using next code:
class MainWindow(QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
uic.loadUi('UI/Qt/source/MainWindow.ui', self)
So, I wanted to know, how do I bind menu bar actions to functions.
Is there any way I can do something like this?
self.getActionByName("actionTest_Action").connect(self.do_something)
It is not necessary to use findChild when using loadUi since this method adds the object to the attributes of the class using the objectName as a name, for example in this particular case a cleaner code than the other answer is:
class MainWindow(QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
uic.loadUi('UI/Qt/source/MainWindow.ui', self)
self.actionTest_Action.triggered.connect(self.test)
def test(self):
print("Test")
So, answering my own question..
One way to do this, is to find an action by using FindChild(QAction, "ActionName") function, and then bind a function using connect() function
class MainWindow(QMainWindow):
def __init__(self):
super(MainWindow, self).__init__()
uic.loadUi('UI/Qt/source/MainWindow.ui', self)
action = self.findChild(QAction, "actionTest_Action")
action.triggered.connect(self.test)
def test(self):
print("Test")

How to hide a window in the constructor immediately after creation?

I want to hide a window immediately after it is created. It works only if I do this with the help of button or something.
class Example(QWidget):
def __init__(self, parent=None):
super(Example, self).__init__(parent)
self.hide() # doesn't work
self.btn = QPushButton('Hide', self)
self.btn.clicked.connect(self.click) # works
self.btn.show()
def click(self): # works
self.hide()
Apparently it seems that the code should work. What may be happening is that you are calling show() after creating the object. For example:
example = Example()
example.show()
Read this answer about hide() and show(): What's the difference in Qt between setVisible, setShown and show/hide
You can use QtCore.QTimer
class Example(QWidget):
def __init__(self, app):
QWidget.__init__(self)
QTimer.singleShot(0, self.hide)

what is the best way to embed program logic that seats in some algorithm class into pyqt4 user interface

class SomNetwork(object):
def __init__(self, dataset):
# some parameters that are not important here
pass
def one_step_learn(self, k, sigma_0, gamma_0, alfa, mcolor,population_of_ids):
pass
def learn(self):
pass
class StartQT4(QtGui.QMainWindow):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.ui = Ui_QSom()
self.ui.setupUi(self)
self.frame = MyFrame(self)
self.setCentralWidget(self.frame)
self.frame.start()
self.show()
class MyFrame(QtGui.QFrame):
simulationSpeed = 5000
def __init__(self, parent):
super(Ramka, self).__init__(parent)
self.init_Board()
def init_Board(self):
self.timer = QtCore.QBasicTimer()
I would like to be able to interact with SomNetwork class in order to be able to call its methods from within inside of the MyFrame class methods. Are there any special design patterns that would suit this example the most or should I just add instance of the class as a field to the MyFrame class.
Thanks of your help in advance!
I don't know if your question is heading towards this, but for your network you could try to subclass a QtCore.QObject instead. On the whole you should instance your network as a member of your QMainWindow, so your frame and the net can interact via signals and slots.
... By the way, there is a little flaw in your code, when you call the constructor of a QWidget in the subclass of a QMainWindow.

QStyledItemDelegate with QComboBox: Shows Index and not Text

I have a QStyledItemDelegate for a table. In one cell I have a QComboBox created through the delegate's createEditor. I add some items to the combobox listing via self.addItem("an item"); however, when I go into the table and actually select the items I have added, they get replaced with index values starting from 0.
How can I have the QComboBox display the actual text I added in addItem instead of the index they're getting stored in?
Here is a small standalone example of my problem:
import sys
from PySide import QtCore, QtGui, QtSql
class EditDelegate(QtGui.QStyledItemDelegate):
def __init__(self, parent=None):
super(EditDelegate, self).__init__(parent)
def createEditor(self, parent, option, index):
editor = TheEditor(parent)
return editor
class TheEditor(QtGui.QComboBox):
def __init__(self, parent=None):
super(TheEditor, self).__init__(parent)
self.addItem("Item 1")
self.addItem("Item 2")
self.addItem("Item 3")
self.setEditable(True)
class TheTable(QtGui.QTableWidget):
def __init__(self, columns, parent=None):
super(TheTable, self).__init__(parent)
self.setItemDelegate(EditDelegate())
self.setEditTriggers(QtGui.QAbstractItemView.AllEditTriggers)
self.setColumnCount(1)
self.setRowCount(1)
self.setHorizontalHeaderLabels(["QCombo"])
class MainWindow(QtGui.QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.setCentralWidget(TheTable(self))
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
frame = MainWindow()
frame.show()
app.exec_()
Updating PySide to the latest version resolves the issue.
It seems that the default combobox delegate is messing up with the data it receives.You could have fixed that with a custom delegate to paint the correct data. But since you have already solved it, Congratulations!.

PySide using GUI elements in another class

I am making an application in Qt using PySide. In my main.py I have a class called Program which sets up the ui and I have another class which has functions pertaining to a certain area. For instance I have an area which has a start and a clear button. I define the functions in class RunArea and connect the signals in class Program but nothing happens. Here is the code.
class Program(QtGui.QMainWindow, Interface.Ui_MainWindow):
def __init__(self, parent=None):
super(Program, self).__init__(parent)
self.setupUi(self)
self.runArea = RunArea()
self.startButton.clicked.connect(self.runArea.start)
self.clearButton.clicked.connect(self.runArea.clear)
class RunArea(QtGui.QMainWindow, Interface.Ui_MainWindow):
def __init__(self, parent=None):
super(RunArea, self).__init__(parent)
self.setupUi(self)
def start(self):
self.log.setPlainText("log entry")
def clear(self):
self.runTree.clear()
What I expect to happen is that "log entry" will be put in a QTextEdit(defined in setupUi) when I click start. And when I click clear a TreeWidget with name runTree will be cleared. I know that the signals are working, but nothing is showing up. May someone please explain why it is not working?
I don't know exactly why/how your code isn't working, although I suspect it has something to do with the inheritance not referring to the same object in the both classes.
However, this is how this should be done:
class Program(QtGui.QMainWindow, Interface.Ui_MainWindow):
def __init__(self, parent=None):
super(Program, self).__init__(parent)
self.setupUi(self)
self.runArea = RunArea(self)
self.startButton.clicked.connect(self.runArea.start)
self.clearButton.clicked.connect(self.runArea.clear)
class RunArea():
def __init__(self, parent=None):
self.parent = parent
def start(self):
self.parent.log.setPlainText("log entry")
def clear(self):
self.parent.runTree.clear()

Categories

Resources