PySide using GUI elements in another class - python

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()

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.

Data not showing in pyqt UI

I created a button in a main window that when clicked will bring up a search window with a tree widget containing rows of data from a MySql database. If I were to open the search window through the .py file on its own it displays the data, but when I open it through the button I programmed, no data is shown. This is the code for the program that runs the main window and creates a button function to open the search window:
from PyQt4 import QtGui
from MainMenu import Ui_MainWindow
from StudentSearch import Ui_Student_search
import DB_manager_students
class MainWindow(Ui_MainWindow):
def __init__(self, parent=None):
QtGui.QMainWindow.__init__(self, parent)
self.setupUi(self)
self.pushButton_3.clicked.connect(self.handleButton)
self.window2 = None
def handleButton(self):
if self.window2 is None:
self.window2 = Student_search()
self.window2.show()
class Student_search(Ui_Student_search):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.setupUi(self)
if __name__ == '__main__':
import sys
app = QtGui.QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())
What am I doing wrong? And why is it that it will display the data if I open it by itself, but not when I open it like so?
Edit:
From Student_search.py
class Ui_Student_search(QtGui.QWidget):
def __init__(self, database, tableName):
QtGui.QWidget.__init__(self)
self.dbu = DB_manager_students.DatabaseUtility(database, tableName)
self.setupUi(self)
self.UpdateTree()
(...)
def UpdateTree(self):
col = self.dbu.GetColumns()
table = self.dbu.GetTable()
for c in range(len(col)):
self.StudentTreeWidget.headerItem().setText(c, col[c][0])
self.StudentTreeWidget.clear()
for item in range(len(table)):
QtGui.QTreeWidgetItem(self.StudentTreeWidget)
for value in range(len(table[item])):
self.StudentTreeWidget.topLevelItem(item).setText(value, str(table[item][value]))
Edit:
This is your base widget class
class Ui_Student_search(QtGui.QWidget):
def __init__(self, database, tableName):
QtGui.QWidget.__init__(self)
self.dbu = DB_manager_students.DatabaseUtility(database, tableName)
self.setupUi(self)
self.UpdateTree()
When you instantiate Ui_Student_search(), the Ui_Student_search.__init__() method runs, which creates a database utility, creates the GUI, and runs UpdateTree().
Now, you create a new class -- Student_search -- that inherits from the Ui_Student_search class
class Student_search(Ui_Student_search):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
self.setupUi(self)
But when this class is instantiated and Student_search.__init__() is run, it only does half of the things that Ui_Student_search.__init__() was doing. It doesn't create the database manager or update the tree.
What you should be doing is calling the parent class __init__ method so that Ui_Student_search.__init__() can run and do all those things. Also realize that you'll need to pass database and tablename arguments to the Ui_Student_search.__init__ method.
class Student_search(Ui_Student_search):
def __init__(self, database, tablename, parent=None):
Ui_Student_search.__init__(self, parent, database, tablename)
Python has an even simpler syntax to call methods on the base parent class.
class Student_search(Ui_Student_search):
def __init__(self, database, tablename, parent=None):
super(Student_search, self).__init__(parent, database, tablename)
This also means that you'll need to update your MainWindow to feed the necessary contructor arguments to Student_search
def handleButton(self):
if self.window2 is None:
database = '???'
tablename = 'xxx'
self.window2 = Student_search(database, tablename, parent=self)
self.window2.show()

Menus and toolbar

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.

Categories

Resources