Access QT Designer Objects Programmatically - python

Disclaimer: New to both python and qt designer
QT Designer 4.8.7
Python 3.4
PyCharm 5.0.3
Question - How do I add controls to the main form or a scroll area widget on the main form (created in QT Designer) programmatically?
I have created a MainWindow in qt designer and added my widgets. The following is the entire test program in PyCharm:
import sys
from PyQt4 import QtGui, QtCore, uic
from PyQt4.QtGui import *
from PyQt4.QtCore import *
qtCreatorFile = "programLauncher.ui"
Ui_MainWindow, QtBaseClass = uic.loadUiType(qtCreatorFile)
class MyApp(QtGui.QMainWindow, Ui_MainWindow):
def __init__(self):
QtGui.QMainWindow.__init__(self)
Ui_MainWindow.__init__(self)
self.setupUi(self)
# Cannot resize or maximize
self.setFixedSize(1045, 770)
# Add button test
self.dateLabel = QtGui.QLabel("Test")
self.pushButton = QtGui.QPushButton('Test button')
# self.scrollArea_programs.addWidget()
grid = QtGui.QGridLayout()
# self.scrollArea_programs.addWidget(self.pushButton)
grid.addWidget(self.dateLabel,0,0)
grid.addWidget(self.pushButton,0,1)
self.setLayout(grid)
self.pushButton_exit.clicked.connect(self.closeEvent)
def closeEvent(self):
QtGui.QApplication.quit()
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
window = MyApp()
window.show()
sys.exit(app.exec_())
As you can see I tried to add controls to a grid but nothing shows up when the program runs - I have also tried to add a control to the scroll area. Can someone help me to just add 1 control to the scroll area at run time - so then I can know the proper way to do it or "a" proper way to do this.
Thanks in advance

Without having access to your programLauncher.ui and making minimal changes to your posted code, you can add your UI elements to the window like so:
from PyQt4 import QtGui
import sys
class MyApp(QtGui.QMainWindow):
def __init__(self):
QtGui.QMainWindow.__init__(self)
# Cannot resize or maximize
self.setFixedSize(1045, 770)
widget = QtGui.QWidget(self)
self.setCentralWidget(widget)
# Add button test
self.dateLabel = QtGui.QLabel("Test")
self.pushButton = QtGui.QPushButton('Test button')
grid = QtGui.QGridLayout()
grid.addWidget(self.dateLabel, 0, 0)
grid.addWidget(self.pushButton, 0, 1)
widget.setLayout(grid)
self.pushButton.clicked.connect(self.closeEvent)
def closeEvent(self, event):
QtGui.QApplication.quit()
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
window = MyApp()
window.show()
sys.exit(app.exec_())
This will get the controls on the screen, although the layout leaves a lot to be desired. You may have to make modifications to this based on what's in your .ui file. One thing that you'll want to note in this example is that the QMainWindow needs a central widget (widget in the example above). You then set the layout on that widget.

You can use the designer to create your .ui file
The you can load it in your .py using something like:
from PyQt4 import QtCore, QtGui, uic
class my_win(QtGui.QMainWindow):
def __init__(self):
self.ui = uic.loadUi('my_ui.ui',self)
then you can access all your widgets with something like
self.ui.actionQuit.triggered.connect(QtGui.qApp.quit)
or
self.ui.my_button.triggered.connect(self.do_someting)

Thanks to JCVanHamme (the programLauncher.ui hint) and also outside help I now learned most of what I need to know to access MainWindow at run time. So for anyone interested in this beginner tip:
Take a blank form in QT Designer
Add a control
Run pyuic4 batch file
Take a look at the generated .py file to learn EVERYTHING about how to add controls.
Don't let the power go to your head - cheers

Related

Pyqt5 multiple widgets

I want to create a pyqt5 application of which, I want to track every button click in the qtextbrowser.
To make it simple to see and also to understand, I want to import different qwidgets to a qmainwindow and build the QMainwindow application in the end.
Evary QWidget has their individual buttons, comboboxes and radiobuttons. I want to track all the activities by appending that activity in a QTextBrowser (which I will import to main window).
(If i click a button_A on a QWidget_1, I want to append the info msg as "Button_A has been clicked" on the QTextBrowser)
I can understand the process of doing this, when we work on a single widget application. But I want to create/build/complile different QWidgets and import that all to a QMainWindow Application (WHich will be my full fledged application).
Does anybody know hoe to track it?
import sys
from PyQt5.QtWidgets import *
from PrintWidget import PrinterWidget
from CameraWidget import CameraWidget
from LaserWidget import LaserWidget
from textbrowser import TextDisplay
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
layout_H = QHBoxLayout()
layout = QVBoxLayout()
layout.addLayout(layout_H)
layout_H.addWidget(PrinterWidget(self))
layout_H.addWidget(CameraWidget(self))
layout.addWidget(LaserWidget(self))
self.browser = TextDisplay()
layout_H.addWidget(self.browser)
self.central_widget = QWidget(self)
self.central_widget.setLayout(layout)
self.setCentralWidget(self.central_widget)
if __name__ == '__main__':
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())
In the above example, I could able to import the textbrowser as a widget to my mainwindow. But I could not ttrack the activities of individual widgets.

Unable to add a QTextEdit inside QTreeWidget

I'm trying to add an option for a QTreeWidget to have multi line editing, which I would assume will require a QTextEdit. The problem is that the examples I've found online just do not work.
The answers I've found have all pointed to using tree.setItemWidget(item, column, widget), but If I add that line, the window just doesn't appear at all. What am I doing wrong in this case?
Here is my example code that has the issue:
import sys
from Qt import QtWidgets, QtCore
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None, **kwargs):
super(MainWindow, self).__init__(parent, **kwargs)
#Add tree widget to window
tree = QtWidgets.QTreeWidget()
tree.setHeaderItem(QtWidgets.QTreeWidgetItem(['col1', 'col2']))
self.setCentralWidget(tree)
#Create items
topLevelButton = QtWidgets.QPushButton('button')
topLevelItem = QtWidgets.QTreeWidgetItem(['test button', 'line edit'])
topLevelItem.setFlags(topLevelItem.flags() | QtCore.Qt.ItemIsEditable)
#Add items to tree widget
tree.addTopLevelItem(topLevelItem)
tree.setItemWidget(topLevelItem, 0, topLevelButton) #the window will not load if this line is not commented out
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
window = MainWindow()
app.setActiveWindow(window)
window.show()
sys.exit(app.exec_())
I've tried it in PySide (2.7) and PySide2 (3.7).
Edit: For Python 3 at least, it seemed to be an issue with PySide2, where forcing PyQt5 somehow fixed whatever it was. I'm still unable to launch with Python 2 as I can't really install PyQt4.
Edit 2: It actually causes a crash if you use it in a program such as Nuke that uses PySide, I may need to ask a more specific question if I can't figure it out from this one.
Sorry, PyQt5 is working.
import sys
#from Qt import QtWidgets, QtCore
from PyQt5 import QtWidgets, QtCore # <---
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None, **kwargs):
super(MainWindow, self).__init__(parent, **kwargs)
# Add tree widget to window
tree = QtWidgets.QTreeWidget()
tree.setHeaderItem(QtWidgets.QTreeWidgetItem(['col1', 'col2']))
self.setCentralWidget(tree)
# Create items
topLevelButton = QtWidgets.QPushButton('button')
topLevelItem = QtWidgets.QTreeWidgetItem(['test button', 'line edit'])
topLevelItem.setFlags(topLevelItem.flags() | QtCore.Qt.ItemIsEditable)
# Add items to tree widget
tree.addTopLevelItem(topLevelItem)
tree.setItemWidget(topLevelItem, 0, topLevelButton) # ??? the window will not load if this line is not commented out
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
window = MainWindow()
app.setActiveWindow(window) # ???
window.show()
sys.exit(app.exec_())

PyQt how to perform function BEFORE GUI resize event

In PyQt4, is there a way to suspend resize of a window until a function is completed?
My problem is that I have created a window with a text edit that might contain large amounts of text. Since I switched to working with a grid layout, the text edit gets resized as well, and when there is a lot of text, the application hangs. I tried overriding resizeEvent to clear text edit text at resize but the application still hangs, since it is clearing the text only AFTER resizing.
Other solutions are welcomed as well.
The python code (and a link to the .ui file):
import sys
from PyQt4 import QtGui, uic, QtCore
from PyQt4.QtGui import QDesktopWidget
qtCreatorMainWindowFile = "mainwindow.ui"
Ui_MainWindow, QtBaseClass = uic.loadUiType(qtCreatorMainWindowFile)
class MainWindow(QtBaseClass, Ui_MainWindow):
def __init__(self):
QtBaseClass.__init__(self)
self.setupUi(self)
# Set window size to 4/5 of the screen dimensions
sg = QDesktopWidget().screenGeometry()
self.resize(sg.width()*4/5, sg.height()*4/5)
self.clearTextBrowserButton.clicked.connect(self.ClearTextBrowsers)
#staticmethod
def WriteToTextBrowser(string, text_browser):
cursor = text_browser.textCursor()
cursor.movePosition(QtGui.QTextCursor.End)
cursor.insertText(string)
text_browser.setTextCursor(cursor)
text_browser.ensureCursorVisible()
def ClearTextBrowsers(self):
self.textBrowser.clear()
# def resizeEvent(self,event):
# print "resize"
# self.ClearTextBrowsers()
app = QtGui.QApplication(sys.argv)
window = MainWindow()
window.show()
for i in range(1,100000):
window.WriteToTextBrowser("TESTTESTTESTTESTTESTTESTTESTTESTTESTTESTTESTTESTTESTTESTTESTTESTTESTTESTTESTTESTTESTTESTTESTTESTTESTTESTTESTTESTTESTTESTTESTTEST\r\n",window.textBrowser)
sys.exit(app.exec_())
The ui. file:
https://www.dropbox.com/s/y3hxp6mjhfpv2hy/mainwindow.ui?dl=0
I found a workaround that seems to work so far. I added an event filter that catches "Move" or "WindowStateChange" QEvents. These seem to happen before the actual resize (the prior works for clicking and stretching and the latter for maximizing/minimizing). The downside is that simply moving the window clears the text edit, but it is a price I'm willing to pay.
The added code (inside MainWindow):
self.installEventFilter(self)
def eventFilter(self, source, event):
if (event.type() == QtCore.QEvent.Move or event.type() == QtCore.QEvent.WindowStateChange):
self.file.write(self.textBrowser.toPlainText())
self.ClearTextBrowsers()
return QtBaseClass.eventFilter(self, source, event)

How do I open sub window after I click on button on main screen in PyQt4

HI I am trying to make a simple converter.
I have used PyQt4 designed to make the Gui
I want to know how launch a new window after I click on the individual button.
This is the interface I have created using PyQt4 Designer.
Here is the Image link :
and I want to launch this windows when I click on currency button.
Here is the Image Link:
Here is my code for main.py
from PyQt4 import QtGui
from main_screen import mainscreen
def main():
import sys
qApp = QtGui.QApplication(sys.argv)
aw = mainscreen()
aw.show()
sys.exit(qApp.exec_())
if __name__ == '__main__':
main()
and code for mainscreen.py
from PyQt4 import QtCore, QtGui
from window_main import Ui_MainWindow
class mainscreen(QtGui.QMainWindow, Ui_MainWindow):
def __init__(self, parent=None):
super(mainscreen,self).__init__(parent)
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
How can I open new window after I click on currency button (object name for currency button is "currency_bt")
and do I have to write the code for currency in same window or I have to write in new window.
How do I do it.
I am new to Python Gui programming.
Each GUI form that you create in Qt Designer needs to be converted into a python module using pyuic. So, to start with, you need to do the same for currency.ui that you did for window_main.
Now you can import your currency window class into mainscreen.py, and connect a button to handler so you can display it.
The code would look something like this:
from PyQt4 import QtCore, QtGui
from window_main import Ui_MainWindow
from currency import Ui_CurrencyWindow
class CurrencyWindow(QtGui.QMainWindow, Ui_CurrencyWindow):
def __init__(self, parent=None):
super(CurrencyWindow, self).__init__(parent)
self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
self.setupUi(self)
class MainScreen(QtGui.QMainWindow, Ui_MainWindow):
def __init__(self, parent=None):
super(MainScreen, self).__init__(parent)
self.setupUi(self)
self.currencyButton.clicked.connect(self.handleCurrencyButton)
def handleCurrencyButton(self):
window = CurrencyWindow(self)
window.show()
After looking at this example code, it will probably occur to you that you are going to end up importing a lot of modules, and have a lot of boiler-plate code to write for each one of them (which is not much fun).
So I would advise you to consider changing your GUI design, so that you have one main window containing a tabwidget, and then have a separate tab for each of your converters. This will not only make your application much easier to write, but it should also make it a lot nicer to use.
I'm making my bachelor thesis in PyQt4. First I also wanted to use the designer (generating code is nice), but afterall I was not using it during my work. Maybe it's a matter of taste.
But for your question (I did this without the QtDesigner):
Let's say we have a main window class:
import sys
from PyQt4 import QtCore, QtGui
class mainscreen(QtGui.QMainWindow):
def __init__(self, parent=None):
super(mainscreen,self).__init__(parent)
self.button = QtGui.QPushButton("push")
self.button.clicked.connect(self.pushed)
#pyqtSlot()
def pushed(self):
# in this section here you can create the new window and show it
qApp = QtGui.QApplication(sys.argv)
aw = mainscreen()
aw.show()
sys.exit(qApp.exec_())
There are some good tutorials (http://zetcode.com/gui/pyqt4/ helped me getting started).
Make two programs: main_win.py and second_win.py, then in main_win.py put this lines:
from os import system as sh //In the begin
def openewin(self): //In the class main_win
sh("python second_win.py")
Ready, just connect the push button to function openewin!

Hide an action without disabling it

I need to control my GUI with shortcuts, so I created some actions to assign the shortcuts. However, I have to put the actions in a menu (so they are visible) to enable them. And some of this action are very basic, like change tab, and don't deserve to appear in a menu.
Is there a way to hide them without disabling them ?
self.changeTabAction.setVisible(False)
This line hides the action, but disables it.
Just add it to your widget with addAction. It will be added to your widget but it wont be visible. Here is an example:
import sys
from PySide import QtGui, QtCore
class Window(QtGui.QWidget):
def __init__(self):
super(Window, self).__init__()
action = QtGui.QAction(self)
action.setShortcut('Ctrl+t')
action.triggered.connect(self.on_triggered)
self.addAction(action)
def on_triggered(self):
print('triggered')
app = QtGui.QApplication(sys.argv)
w = Window()
w.show()
sys.exit(app.exec_())

Categories

Resources