I have googled for a long time and I could'nt find a solution to my problem.
I am trying to create a window in which you can display multiple instances of another widget, just like you can see in the picture. The widgets are supposed to be different uploads you can manage with them. This is the code I wrote and
self.UploadArea.addWidget(uic.loadUi('gui_files/module.ui'))
is supposed to open the Widget inside a QWidget called "UploadArea" it probably is coded like garbage and does not make any sense but it would be nice if you could tell me an elegant answer to my problem.
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, *args):
super(MainWindow, self).__init__(*args)
uic.loadUi('gui_files/mainWindow.ui', self)
self.upload.clicked.connect(self.buttonClicked)
def buttonClicked(self):
print("Test")
self.UploadArea.addWidget(uic.loadUi('gui_files/module.ui'))
app = QtWidgets.QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())
Widget and MainWindow
How it is supposed to look
Thank you for your help
Lennard
You are close - you can create multiple instances of a QWidget and then add these to your QMainWindow. Here is a minimal working example:
from PyQt5.QtWidgets import *
from PyQt5.uic import loadUi
class SubWidget( QWidget ) :
def __init__ ( self, parent = None ) :
super( SubWidget, self ).__init__( parent )
button = QPushButton( 'toggle' )
checkbox = QCheckBox( 'check' )
button.clicked.connect( checkbox.toggle )
hLayout = QHBoxLayout( self )
hLayout.addWidget( button )
hLayout.addWidget( checkbox )
self.setLayout( hLayout )
class Window( QMainWindow ) :
def __init__ ( self, parent = None ) :
super( Window, self ).__init__( parent )
# loadUi( 'main-something.ui', self )
button = QPushButton( 'add' )
button.clicked.connect( self.add )
self.vLayout = QVBoxLayout( self )
self.vLayout.addWidget( button )
centralWidget = QWidget()
centralWidget.setLayout( self.vLayout )
self.setCentralWidget( centralWidget )
def add ( self ) :
self.vLayout.addWidget( SubWidget( self ) )
# self.vLayout.addWidget( loadUi( 'sub-something.ui', self ) )
if __name__ == "__main__" :
app = QApplication( [] )
w = Window()
w.show()
app.exec_()
You migth be mistaken by using addWidget() on a QWidget and not a QLayout. Easiest fix on that part, would be adding a layout to your widget:
vLayout = QVBoxLayout ()
UploadArea.setLayout( vLayout )
vLayout.addWidget( loadUi( 'your_file.ui' ) )
please give us feedback, and if something fails, show us the traceback-print
Related
I'm a beginner in WxPython and I've tried experimenting splitting up the code to make it organized and look neater. I've tried it with simple code but it doesn't work. Can anyone please give me a hand?
The code I've tried:
import wx
class text_ctrl ( wx.Panel ):
def __init ( self, parent ):
wx.Panel.__init__ ( self, parent = parent )
text = wx.TextCtrl ( self, pos = ( 100, 100 ) )
class Window ( wx.Frame ):
def __init__ ( self ):
super().__init__ ( parent = None, title = "Learn - Tab TextBox" )
panel = wx.Panel()
text_ctrl ( self )
self.Show()
if __name__ == "__main__":
app = wx.App()
window = Window()
app.MainLoop()
Problem: Textbox doesn't show up ( which is supposed to be the main point ).
For want of a nail the kingdom was lost
You are missing a __
Without the init, nothing occurs when you call text_ctrl
import wx
class text_ctrl ( wx.Panel ):
#def __init ( self, parent ):
def __init__ ( self, parent ):
wx.Panel.__init__ ( self, parent = parent )
text = wx.TextCtrl ( self, pos = ( 100, 100 ) )
class Window ( wx.Frame ):
def __init__ ( self ):
super().__init__ ( parent = None, title = "Learn - Tab TextBox" )
# panel = wx.Panel()
text_ctrl ( self )
self.Show()
if __name__ == "__main__":
app = wx.App()
window = Window()
app.MainLoop()
I would like to implement a custom context menu in a QFileDialog. In the code below, I managed to create a context menu to the main window, but I would like the menu to be displayed when a file is selected : how to know the right widget in the QFileDialog I should apply setContextMenuPolicy ?
import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *
class Window(QWidget):
def __init__(self):
QWidget.__init__(self)
self.myFileDialog = QFileDialog()
self.myFileDialog.setContextMenuPolicy(Qt.CustomContextMenu)
self.myFileDialog.customContextMenuRequested.connect(self.openMenu)
layout = QVBoxLayout()
layout.addWidget(self.myFileDialog)
self.setLayout(layout)
self.action_perso = QAction( "MyOwnMenu", self )
self.connect( self.action_perso, SIGNAL("triggered()"), self.test )
def openMenu(self, position):
menu = QMenu()
menu.addAction(self.action_perso)
menu.exec_(self.myFileDialog.mapToGlobal(position))
def test(self):
print("coucou")
if __name__ == "__main__":
app = QApplication(sys.argv)
window = Window()
window.show()
sys.exit(app.exec_())
I found a solution, which may not be the best. It relies on two elements:
Thank to a personnal function objectTree (shown here but not used) that lists recursively all child objects of the QFileDialog, I identified the right widget, i.e. the QTreeView (I understood that the QTreeView is the right widget by trying to hide successively all QListView and QTreeView widgets). Hence, I can select it by its objectName with self.findChild(QTreeView, "treeView")
Application of setContextMenuPolicy( Qt.ActionsContextMenu ) to this QTreeView. I have also tried to implement a setContextMenuPolicy(Qt.CustomContextMenu), and it worked partially: my menu did appear but under the origin menu that was not unactivaded !
Below is the code I propose :
import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *
class CustomWidget(QFileDialog):
def __init__(self, parent=None):
super(CustomWidget,self).__init__(parent)
# fetch the QTreeView in the QFileDialog
self.myTree = self.findChild(QTreeView, "treeView")
# set the context menu policy to ActionsContextMenu
self.myTree.setContextMenuPolicy( Qt.ActionsContextMenu )
# Define a new action
self.action_perso = QAction( "MyOwnMenu", self.myTree )
self.myTree.addAction( self.action_perso )
# connect this action to a personnal function
self.connect( self.action_perso, SIGNAL("triggered()"), self.myFunction )
def myFunction(self):
print("coucou")
def objectTree(self, objet, plan, j):
""" list recursively all child objects of objet to fetch the right widget """
n = len( objet.children() )
for i, child in enumerate( objet.children() ):
#print("\t"*j, end="")
plan_sup = plan+"."+str(i)
#print( plan_sup, child )
if isinstance(child, QTreeView):
self.listViews.append(child)
self.objectTree(child, plan_sup, j+1)
class MainWidget(QWidget):
def __init__(self, parent=None):
super(MainWidget,self).__init__(parent)
#creation of main layout
mainLayout = QVBoxLayout()
# creation of a widget inside
self.monWidget = CustomWidget()
mainLayout.addWidget( self.monWidget )
self.setLayout( mainLayout )
self.show()
app = QApplication(sys.argv)
window = MainWidget()
sys.exit(app.exec_())
Could you tell me how to create custom panel in NUKE having no spacing (i.e. frameless window)?
At the moment it looks like this:
But I need it to look like this:
This is happening because the panel has several nested widgets each adding their own margin, so you'll need to iterate through the parent widgets and setContentsMargins on each.
"""
Get rid of the margins surrounding custom Panels
"""
import nuke
import PySide.QtCore as QtCore
import PySide.QtGui as QtGui
from nukescripts import panels
def set_widget_margins_to_zero(widget_object):
if widget_object:
target_widgets = set()
target_widgets.add(widget_object.parentWidget().parentWidget())
target_widgets.add(widget_object.parentWidget().parentWidget().parentWidget().parentWidget())
for widget_layout in target_widgets:
try:
widget_layout.layout().setContentsMargins(0, 0, 0, 0)
except:
pass
class Example_Window(QtGui.QWidget):
def __init__(self, parent=None):
QtGui.QWidget.__init__(self, parent)
layout = QtGui.QVBoxLayout()
label = QtGui.QLabel('Margins be-gone!')
label.setStyleSheet('QLabel{background: #eeffcc}')
layout.setContentsMargins(0,0,0,0)
layout.addWidget(label)
self.setLayout(layout)
expandingPolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding,
QtGui.QSizePolicy.Expanding)
label.setSizePolicy(expandingPolicy)
self.setSizePolicy(expandingPolicy)
def event(self, event):
if event.type() == QtCore.QEvent.Type.Show:
try:
set_widget_margins_to_zero(self)
except:
pass
return QtGui.QWidget.event(self, event)
panels.registerWidgetAsPanel('Example_Window', 'Example Widget',
'mwbp.Example_Widget')
to give credit where it's due, I found the solution a while ago here : https://gist.github.com/maty974/4739917 and have posted an integrated example widget.
The only way to make a panel that I know via Python is this (but it's with frame):
class myCustomPanel( nukescripts.PythonPanel ):
def __init__( self ):
nukescripts.PythonPanel.__init__( self, 'myCustomPanel' )
self.update = nuke.PyScript_Knob( 'update', 'Update Info' )
self.info = nuke.Multiline_Eval_String_Knob( 'info', 'Info' )
self.info.setEnabled( True )
self.addKnob( self.update )
self.addKnob( self.info )
def addInfoPanel():
global iPanel
iPanel = myCustomPanel()
return iPanel.addToPane()
paneMenu = nuke.menu( 'Pane' )
paneMenu.addCommand( 'myCustomPanel', addInfoPanel )
In Pyqt, I am trying to make the QHeaderView of a QTableWidget respond to right mouse clicks.
I have subclassed QHeaderView and i have overloaded the mousePressEvent.
Then i can set it as as the header of my custom QTableWidget, the DataTable class. However i don't understand how to set the labels of the header.
Thanks for helping!
Here is some code.
class Header( QtGui.QHeaderView ):
def __init__ ( self, parent ):
QtGui.QHeaderView.__init__( self, QtCore.Qt.Vertical, parent=parent )
def mousePressEvent( self, event ):
if event.button() == QtCore.Qt.RightButton:
do_stuff()
class DataTable( QtGui.QTableWidget ):
def __init__ ( self ):
QtGui.QTableWidget.__init__( self )
self.setShowGrid(True)
self.header = Header( parent = self )
self.header.setClickable(True)
self.setHorizontalHeader( self.header )
def set_header( self, labels ):
???
This sample code should be useful:
import sys
import string
from PyQt4.QtCore import *
from PyQt4.QtGui import *
class Header(QHeaderView):
def __init__(self, parent=None):
super(Header, self).__init__(Qt.Horizontal, parent)
self.setContextMenuPolicy(Qt.CustomContextMenu)
self.customContextMenuRequested.connect(self.ctxMenu)
self.hello = QAction("Hello", self)
self.hello.triggered.connect(self.printHello)
self.currentSection = None
def printHello(self):
data = self.model().headerData(self.currentSection, Qt.Horizontal)
print data.toString()
def ctxMenu(self, point):
menu = QMenu(self)
self.currentSection = self.logicalIndexAt(point)
menu.addAction(self.hello)
menu.exec_(self.mapToGlobal(point))
class Table(QTableWidget):
def __init__(self, parent=None):
super(Table, self).__init__(parent)
self.setHorizontalHeader(Header(self))
self.setColumnCount(3)
self.setHorizontalHeaderLabels(['id', 'name', 'username'])
self.populate()
def populate(self):
self.setRowCount(10)
for i in range(10):
for j,l in enumerate(string.letters[:3]):
self.setItem(i, j, QTableWidgetItem(l))
if __name__ == '__main__':
app = QApplication(sys.argv)
t = Table()
t.show()
app.exec_()
sys.exit()
Short answer:
The QTableWidget has a function called "setHorizontalHeaderLabels", simply supply your headers to it. Like so:
your_table_widget.setHorizontalHeaderLabels(["name", "phone number", "email"])
I would have added this as a comment to pedrotech, but I don't have enough rep for comments.
I just started to lear the PyQt, but I got some problem. Here is my code:
class GUI( QtGui.QMainWindow ):
'''
classdocs
'''
"""**********************************************************************"""
""" Constructor """
"""**********************************************************************"""
def __init__( self, parent = None ):
self.app = QtGui.QApplication( sys.argv )
QtGui.QMainWindow.__init__( self )
"""******************************************************************"""
""" Settintg up the windows """
"""******************************************************************"""
self.resize( 1024, 756 )
self.setWindowTitle( 'Windscanner - Core Module' )
self.setWindowIcon( QtGui.QIcon( 'icons/Windsock.png' ) )
""" Text Area """
self.messageField = QtGui.QTextEdit() # Alternative: QTextEdit
self.messageField.setReadOnly( True )
""" Input """
self.inputLine = QtGui.QLineEdit()
""" Send Button """
sendButton = QtGui.QPushButton( 'TCP: Send' )
sendButton.setStatusTip( 'Send manually inserted message via TCP' )
sendButton.setToolTip( 'Send manually inserted message via TCP' )
self.connect( sendButton, QtCore.SIGNAL( 'clicked()' ), self.f_sendbutton )
sendButton.setGeometry( 300, 300, 250, 150 );
""" Layout """
mainLayout = QtGui.QGridLayout()
mainLayout.addWidget( self.messageField )
mainLayout.addWidget( self.inputLine )
mainLayout.addWidget( sendButton )
""" Widget """
mainWidget = QtGui.QWidget()
mainWidget.setLayout( mainLayout )
self.setCentralWidget( mainWidget )
self.show()
sys.exit( self.app.exec_() )
My question is how can I define the size and geometry of the textarea and the button?
I tryed to use the
setGeometry()
but it not really working.
You can use:
sendButton.setMinimumSize()
and
mainLayout.setRowMinimumHeight()