I want to run my app in different tabs. Rightnow, it is running in main window. I have done some search work on how to create tabs. I found this to be useful, but not sufficient to meet my requirements
Create TAB and create textboxes that take data in the TAB-page
I want to have a feature of adding a new tab (like new tab in chrome)
Below is my code sample. I described what i require in the comments.
from PyQt4 import Qt, QtCore, QtGui
import sys
class Map(QtGui.QMainWindow):
def __init__(self,parentQExampleScrollArea=None,parentQWidget = None):
super(Map,self).__init__()
self.initUI()
#Initialize the UI
def initUI(self):
#Initilizing Menus toolbars
#This must be maintained in all tabbed panes
filename = ""
#Filename is obtained through open file button in file menu
self.filename = filename
def paintEvent(self, e):
qp = QtGui.QPainter()
qp.begin(self)
self.drawPoints(qp,self.filename)
qp.end()
def drawPoints(self, qp,FILENAME=""):
#Read contents in file
#Get the necessary coordinates
#A separate class for storing the info of all the coordinates
#Run a for loop for all the coordinates in the list
#Actually, object is created here and image of that object is set
# as a square using the coordinates
qp.setBrush(QtGui.QColor(255, 0, 20, 200))
qp.drawRect(20,20,75,75)
qp.drawRect(100,20,75,75)
self.update()
#There are many functions to handle keyboard and mouse events
def main():
#How do I modify so that I can have multiple tabs
#And show images of the coordinates in files
#Basically I want to have the feature of opening many files
# and displaying them in UI
#Basically a feature to add a new tab
#like that of in eclipse netbeans sublime etc
app = QtGui.QApplication(sys.argv)
myQExampleScrollArea = Map()
myQExampleScrollArea.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
Thanks in advance.. :)
It's simply to use method int QTabWidget.addTab (self, QWidget widget, QString) to create widget in tab. In each tab, I suggest use QtGui.QWidget more than QtGui.QMainWindow;
Example;
import sys
from PyQt4 import QtGui
class QCustomWidget (QtGui.QWidget):
# Your widget to implement
# Put your override method here
def paintEvent (self, eventQPaintEvent):
currentQPainter = QtGui.QPainter()
currentQPainter.begin(self)
currentQPainter.setBrush(QtGui.QColor(255, 0, 20, 200))
currentQPainter.drawRect(20, 20, 75, 75)
currentQPainter.drawRect(100, 20, 75, 75)
self.update()
currentQPainter.end()
class QCustomTabWidget (QtGui.QTabWidget):
def __init__ (self, parent = None):
super(QCustomTabWidget, self).__init__(parent)
self.addTab(QtGui.QPushButton('Test'), 'Tab 1')
self.addTab(QCustomWidget(), 'Tab 2')
myQApplication = QtGui.QApplication([])
myQCustomTabWidget = QCustomTabWidget()
myQCustomTabWidget.show()
sys.exit(myQApplication.exec_())
So handle with more tab, It's bad to create many line call int QTabWidget.addTab (self, QWidget widget, QString). Anyway, All widget has add in QTabWidget is can reference in ifself. So, your can control element in it by call QWidget QTabWidget.widget (self, int index).
Example to call widget in tab widget;
import os
import sys
from PyQt4 import QtCore, QtGui
class QCustomLabel (QtGui.QLabel):
def __init__(self, imagePath, parentQWidget = None):
super(QCustomLabel, self).__init__(parentQWidget)
self.setPixmap(QtGui.QPixmap(imagePath))
class QCustomWidget (QtGui.QWidget):
def __init__ (self, parentQWidget = None):
super(QCustomWidget, self).__init__(parentQWidget)
self.addQPustButton = QtGui.QPushButton('Open image')
self.addQPustButton.setMaximumWidth(120)
self.addQPustButton.released.connect(self.openImage)
self.workSpaceQTabWidget = QtGui.QTabWidget()
self.workSpaceQTabWidget.setTabsClosable(True)
self.workSpaceQTabWidget.tabCloseRequested.connect(self.closeImage)
allQVBoxLayout = QtGui.QVBoxLayout()
allQVBoxLayout.addWidget(self.addQPustButton)
allQVBoxLayout.addWidget(self.workSpaceQTabWidget)
self.setLayout(allQVBoxLayout)
def openImage (self):
path = QtGui.QFileDialog.getOpenFileName(self, 'Open image')
if not path.isEmpty():
self.workSpaceQTabWidget.addTab(QCustomLabel(path), QtCore.QString(os.path.basename(str(path))))
def closeImage (self, currentIndex):
currentQWidget = self.workSpaceQTabWidget.widget(currentIndex)
currentQWidget.deleteLater()
self.workSpaceQTabWidget.removeTab(currentIndex)
myQApplication = QtGui.QApplication([])
myQCustomWidget = QCustomWidget()
myQCustomWidget.show()
sys.exit(myQApplication.exec_())
Related
all.
I'd like to be able to switch between multiple screens. Meaning, the first one is the main, then when with a button or an external switch is activated I can see the page #2, in that one I may have an other button to return to the first one, or going to #3, etc. Cause I have a main screen for a big RPM meter, but I may want to see instead all three meter on the same page, or view the raw data in an other page, or go to the set-up page or elsewhere in the future development. I'm using the full screen space for my graphic. Maybe something like "hide" or "show" a page with an event of some kind. I have a single class script for every pages so far, but unable to group them in a single one. Thanks for your help
I wrote about this concept several years ago here. I went ahead an reproduced the example from that article:
import wx
import wx.grid as gridlib
class PanelOne(wx.Panel):
""""""
def __init__(self, parent):
"""Constructor"""
wx.Panel.__init__(self, parent=parent)
txt = wx.TextCtrl(self)
class PanelTwo(wx.Panel):
""""""
def __init__(self, parent):
"""Constructor"""
wx.Panel.__init__(self, parent=parent)
grid = gridlib.Grid(self)
grid.CreateGrid(25,12)
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(grid, 0, wx.EXPAND)
self.SetSizer(sizer)
class MyForm(wx.Frame):
def __init__(self):
wx.Frame.__init__(self, None, wx.ID_ANY,
"Panel Switcher Tutorial")
self.panel_one = PanelOne(self)
self.panel_two = PanelTwo(self)
self.panel_two.Hide()
self.sizer = wx.BoxSizer(wx.VERTICAL)
self.sizer.Add(self.panel_one, 1, wx.EXPAND)
self.sizer.Add(self.panel_two, 1, wx.EXPAND)
self.SetSizer(self.sizer)
menubar = wx.MenuBar()
fileMenu = wx.Menu()
switch_panels_menu_item = fileMenu.Append(wx.ID_ANY,
"Switch Panels",
"Some text")
self.Bind(wx.EVT_MENU, self.onSwitchPanels,
switch_panels_menu_item)
menubar.Append(fileMenu, '&File')
self.SetMenuBar(menubar)
def onSwitchPanels(self, event):
""""""
if self.panel_one.IsShown():
self.SetTitle("Panel Two Showing")
self.panel_one.Hide()
self.panel_two.Show()
else:
self.SetTitle("Panel One Showing")
self.panel_one.Show()
self.panel_two.Hide()
self.Layout()
# Run the program
if __name__ == "__main__":
app = wx.App(False)
frame = MyForm()
frame.Show()
app.MainLoop()
The basic idea here is to Hide() one panel and Show() another. You might also want to look at the Notebook controls that wxPython provides as they have a similar functionality.
I'm trying to make a GUI in Qt Designer that has one text entry box and a button off to the side that inserts another text entry box below the first. I would potentially need to do this a dozen times or more.
This is my example code from Qt Designer:
from PySide import QtCore, QtGui
class Ui_Dialog(object):
def setupUi(self, Dialog):
Dialog.setObjectName("Dialog")
Dialog.resize(247, 300)
self.pushButton = QtGui.QPushButton(Dialog)
self.pushButton.setGeometry(QtCore.QRect(110, 10, 75, 23))
self.pushButton.setObjectName("pushButton")
self.lineEdit1 = QtGui.QLineEdit(Dialog)
self.lineEdit1.setGeometry(QtCore.QRect(20, 10, 31, 20))
self.lineEdit1.setObjectName("lineEdit1")
self.lineEdit2 = QtGui.QLineEdit(Dialog)
self.lineEdit2.setGeometry(QtCore.QRect(60, 10, 31, 20))
self.lineEdit2.setObjectName("lineEdit2")
self.retranslateUi(Dialog)
# QtCore.QObject.connect(self.pushButton, QtCore.SIGNAL("clicked()"), Dialog.add_wells) #
QtCore.QMetaObject.connectSlotsByName(Dialog)
def retranslateUi(self, Dialog):
Dialog.setWindowTitle(QtGui.QApplication.translate("Dialog", "Dialog", None, QtGui.QApplication.UnicodeUTF8))
self.pushButton.setText(QtGui.QApplication.translate("Dialog", "PushButton", None, QtGui.QApplication.UnicodeUTF8))
and this is the code to run the GUI:
from PySide.QtGui import *
from PySide.QtCore import *
import sys
import addentryexample
class MainWindow(QDialog, addentryexample.Ui_Dialog):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.setupUi(self)
self.connect(self.pushButton, SIGNAL("clicked()"), self.add_entry)
def add_entry(self):
pass
app = QApplication(sys.argv)
form = MainWindow()
form.show()
app.exec_()
I'm struggling on how to iterate each name of the text box entry so I can pick the values from them later on. I think placing them should just require adding a certain amount to each 'setGeometry' attribute.
Any help would be appreciated!
You can use findChildren:
lineEdits = form.findChildren(QLineEdit)
for lineEdit in lineEdits:
print lineEdit.objectName()
I'm writing a PyQt application that shall feature multiple windows. Right now, I am interested in having one of two windows open at a time (so a click of a button in one window causes a switch to the other window). What is a reasonable way of keeping track of multiple windows in a PyQt application? My initial attempt, as shown below, essentially stores instances of the QtGui.QWidget in data members of a global instance of a simple class.
I'm new to PyQt. Is there a better way to approach this?
#!/usr/bin/env python
import sys
from PyQt4 import QtGui
class Program(object):
def __init__(
self,
parent = None
):
self.interface = Interface1()
class Interface1(QtGui.QWidget):
def __init__(
self,
parent = None
):
super(Interface1, self).__init__(parent)
self.button1 = QtGui.QPushButton(self)
self.button1.setText("button")
self.button1.clicked.connect(self.clickedButton1)
self.layout = QtGui.QHBoxLayout(self)
self.layout.addWidget(self.button1)
self.setGeometry(0, 0, 350, 100)
self.setWindowTitle('interface 1')
self.show()
def clickedButton1(self):
self.close()
program.interface = Interface2()
class Interface2(QtGui.QWidget):
def __init__(
self,
parent = None
):
super(Interface2, self).__init__(parent)
self.button1 = QtGui.QPushButton(self)
self.button1.setText("button")
self.button1.clicked.connect(self.clickedButton1)
self.layout = QtGui.QHBoxLayout(self)
self.layout.addWidget(self.button1)
self.setGeometry(0, 0, 350, 100)
self.setWindowTitle('interface 2')
self.show()
def clickedButton1(self):
self.close()
program.interface = Interface1()
def main():
application = QtGui.QApplication(sys.argv)
application.setApplicationName('application')
global program
program = Program()
sys.exit(application.exec_())
if __name__ == "__main__":
main()
Have a single main window with a QStackedWidget to hold the different interfaces. Then use QStackedWidget.setCurrentIndex to switch between the interfaces.
Also, try to avoid using global references. If you want GUI components to communicate with each other, use signals and slots. You can easily define your own custom signals if there are no suitable built-in ones.
How can I put stuff in the main window? I want to create a line edit in the main window(beneath the menu bar, maybe with some decription laber in front of it). How is this done? I used grid layout and this box layout, nothing works.
(sry for another trivial question, there are only few tutorials on pyside out there, and most of them only cover how to create single windows with buttons ect.)
import sys
from PySide import QtGui, QtCore, QtWebKit
class FirstClass(QtGui.QMainWindow, QtGui.QWidget):
def __init__(self):
super(FirstClass, self).__init__()
self.startingUI()
def startingUI(self):
self.setWindowTitle('Hauptfenster')
self.resize(800, 400)
self.statusBar()
#Menueinstellungen an sich
menue = self.menuBar()
#Actions des Menues:
#datei menue
menuleiste_datei = menue.addMenu('File')
datei_exit = QtGui.QAction('Exit', self)
datei_exit.setStatusTip('Close the programm')
menuleiste_datei.addAction(datei_exit)
datei_exit.triggered.connect(self.close)
#Einstellungen menue
menuleiste_configurations = menue.addMenu('Configurations')
configurations_settings = QtGui.QAction('Settings', self)
configurations_settings.setStatusTip('Configurations(Settings)')
menuleiste_configurations.addAction(configurations_settings)
configurations_settings.triggered.connect(self.newwindow)
self.lineedit = QtGui.QLineEdit()
self.layout = QtGui.QHBoxLayout()
self.layout.addWidget(self.lineedit)
self.setLayout(self.layout)
self.show()
def newwindow(self):
self.wid = QtGui.QWidget()
self.wid.resize(250, 150)
self.setWindowTitle('NewWindow')
self.wid.show()
def main():
app = QtGui.QApplication(sys.argv)
start = FirstClass()
sys.exit(app.exec_())
if __name__== '__main__':
main()
I do not believe creating a class with a multiple inheritance is recommended best practice. If an attribute is not found in FirstClass, then it searches left to right (QtGui.QMainWindow to QtGui.QWidget). From my perspective, this would turn into a nightmare to support and debug. My guess this is why the self.layout is not working properly.
I made separate classes for QtGui.QMainWindow and QtGui.QWidget. FirstWindowClass sets the central widget as FirstWidgetClass. FirstWidgetClass has your QLineEdit and I went ahead and inserted a label. I changed QHBoxLayout to QGridLayout to help you understand how it works.
Some tips from my learning experiences with Python and Pyside these past couple months:
Remember you can always look at PyQt examples and majority will work directly with PySide modules.
I recommend looking over http://srinikom.github.io/pyside-docs/index.html as a lot of the modules have simple examples.
For my personal project, a lot of the solutions to my Qt questions were in C++ so do not be afraid to convert it to python.
import sys
from PySide import QtGui, QtCore, QtWebKit
class FirstWindowClass(QtGui.QMainWindow):
def __init__(self):
super(FirstWindowClass, self).__init__()
self.setWindowTitle('Hauptfenster')
self.resize(800, 400)
self.statusBar()
# Set central widget that expands to fill your window
self.main_widget = FirstWidgetClass(self)
self.setCentralWidget(self.main_widget)
#Menueinstellungen an sich
menue = self.menuBar()
#Actions des Menues:
#datei menue
menuleiste_datei = menue.addMenu('File')
datei_exit = QtGui.QAction('Exit', self)
datei_exit.setStatusTip('Close the programm')
menuleiste_datei.addAction(datei_exit)
datei_exit.triggered.connect(self.close)
#Einstellungen menue
menuleiste_configurations = menue.addMenu('Configurations')
configurations_settings = QtGui.QAction('Settings', self)
configurations_settings.setStatusTip('Configurations(Settings)')
menuleiste_configurations.addAction(configurations_settings)
configurations_settings.triggered.connect(self.newwindow)
# Open the window
self.show()
def newwindow(self):
self.wid = QtGui.QWidget()
self.wid.resize(250, 150)
self.wid.setWindowTitle('NewWindow')
self.wid.show()
class FirstWidgetClass(QtGui.QWidget):
def __init__(self, parent=None):
super(FirstWidgetClass, self).__init__()
self.label_example = QtGui.QLabel('Enter Data:')
self.lineedit = QtGui.QLineEdit()
self.layout = QtGui.QGridLayout()
self.layout.addWidget(self.label_example, 0, 0)
self.layout.addWidget(self.lineedit, 0, 1)
self.setLayout(self.layout)
self.show()
def main():
app = QtGui.QApplication(sys.argv)
start = FirstWindowClass()
sys.exit(app.exec_())
if __name__== '__main__':
main()
I'm trying to open a window (QWidget) when clicking on a button. My problem is that the second window doesn't show up when I click on the button no matter what I've tried. The two windows are created using QTDesigner.
Here is a little snippet explaining what I'm trying to do:
from PyQt4.QtGui import *
from PyQt4.QtCore import *
from win1 import *
from win2 import *
import sys
class win1(QWidget, Ui_Win1):
def __init__(self, parent = None):
self.parent = parent
QWidget.__init__(self)
self.setupUi(parent)
self.connect(self.pushButton, SIGNAL("clicked()"), self.on_btn_clicked)
def on_btn_clicked(self):
self.child = win2(self.parent)
self.child.show()
class win2(QWidget, Ui_Win2):
def __init__(self, parent = None):
QWidget.__init__(self)
self.setupUi(parent)
def main(args):
app = QApplication(args)
win = QWidget()
a = win1(win)
win.show()
result = app.exec_()
if __name__=="__main__":
main(sys.argv)
What am I missing here ?
Thanks.
Not sure, but two random thoughts:
If you add a print statement to on_btn_clicked, do you see anything when you click on the button? This would diagnose whether it's an event triggering issue
Does it work if you change the setupUI(parent) commands to setupUI(self)?