I have created my .ui file in Qt Designers I am then using loadUI() to load it into my app below.
import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.uic import loadUi
class Life2Coding(QDialog):
def __init__(self):
super(Life2Coding, self).__init__()
loadUi('new.ui', self)
app = QApplication(sys.argv)
widget=Life2Coding()
widget.show()
sys.exit(app.exec_())
However when I go to run this the images will not show up, which is odd as in the Qt designer when I click preview the images actually show up.
Also on a side note if its helpful I am using a xz.prc file for a prefix / path which is how the Qt designer is writing the code linking to the images.
Please could you suggest ways in which I might get the images from new.ui show in my app? Also all widgets work including labels its just the images that do not show up when I run this.
Thanks
Carl
.ui file in its native format
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Dialog</class>
<widget class="QDialog" name="Dialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>1343</width>
<height>965</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<widget class="QLabel" name="label">
<property name="geometry">
<rect>
<x>730</x>
<y>740</y>
<width>521</width>
<height>171</height>
</rect>
</property>
<property name="frameShape">
<enum>QFrame::Box</enum>
</property>
<property name="text">
<string/>
</property>
<property name="pixmap">
<pixmap resource="xz.qrc">:/newPrefix/me.jpg</pixmap>
</property>
</widget>
<widget class="QLabel" name="label_2">
<property name="geometry">
<rect>
<x>60</x>
<y>530</y>
<width>651</width>
<height>271</height>
</rect>
</property>
<property name="text">
<string/>
</property>
<property name="pixmap">
<pixmap resource="xz.qrc">:/newPrefix/logo.png</pixmap>
</property>
</widget>
<widget class="QLabel" name="label_3">
<property name="geometry">
<rect>
<x>930</x>
<y>70</y>
<width>331</width>
<height>301</height>
</rect>
</property>
<property name="styleSheet">
<string notr="true">image: url(:/newPrefix/logo.png);</string>
</property>
<property name="text">
<string>TextLabel</string>
</property>
</widget>
<widget class="QLabel" name="label_4">
<property name="geometry">
<rect>
<x>280</x>
<y>180</y>
<width>68</width>
<height>19</height>
</rect>
</property>
<property name="text">
<string>TextLabel</string>
</property>
</widget>
</widget>
<resources>
<include location="xz.qrc"/>
</resources>
<connections/>
</ui>
xz.prc
<RCC>
<qresource prefix="newPrefix">
<file>logo.png</file>
<file>me.jpg</file>
</qresource>
</RCC>
xz_rc.py
This is after it has been converted from xz.prc
from PyQt5 import QtCore
qt_resource_data = b
qt_version = QtCore.qVersion().split('.')
if qt_version < ['5', '8', '0']:
rcc_version = 1
qt_resource_struct = qt_resource_struct_v1
else:
rcc_version = 2
qt_resource_struct = qt_resource_struct_v2
def qInitResources():
QtCore.qRegisterResourceData(rcc_version, qt_resource_struct, qt_resource_name, qt_resource_data)
def qCleanupResources():
QtCore.qUnregisterResourceData(rcc_version, qt_resource_struct, qt_resource_name, qt_resource_data)
qInitResources()
The .qrc file maybe what Qt designer uses to connect to images however when I am loading the .ui file into my .py app it is having trouble using the .qrc file so instead I need to create a .py version of .qrc.
Go to the directory that .qrc is located in using command prompt and write in this command. Note xz is just what I called it yours may be called thing else.
pyrcc5 xz.qrc -o xz_rc.py
Then import this into your .py app no need to add .py on the end as we are importing this as a module.
import xz.rc
Now your .py app shall display images thanks to having access to a format it can now understand.
Related
The interface is shown completely in Qt, but all the buttons are not shown when running the python script.
in Qt:
in script:
Searched online, didn't find a similar issue.
Thanks in advance if anyone can help me on that!
Additional info
The python script:
class Main(QMainWindow):
def __init__(self, parent=None):
QWidget.__init__(self, parent)
uic.loadUi("edytor.ui", self)
self.layout = []
self.rgb_layout = []
self.loadlayout.clicked.connect(self.getfile)
if __name__ == "__main__":
def run_app():
app = QApplication(sys.argv)
mapp = Main()
mapp.show()
sys.exit(app.exec_())
run_app()
The script for "edytor.ui":
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>notepad</class>
<widget class="QWidget" name="notepad">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>659</width>
<height>191</height>
</rect>
</property>
<property name="windowTitle">
<string>Scan</string>
</property>
<widget class="QPushButton" name="loadlayout">
<property name="geometry">
<rect>
<x>50</x>
<y>90</y>
<width>141</width>
<height>31</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>-1</pointsize>
<weight>50</weight>
<italic>false</italic>
<bold>false</bold>
</font>
</property>
<property name="styleSheet">
<string notr="true">background: white;
border-style: outset;
border-width: 0.5px;
border-radius: 5px;
border-color: gray;
font: 14px;</string>
</property>
<property name="text">
<string>Load Layout Image</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="autoDefault">
<bool>false</bool>
</property>
<property name="default">
<bool>true</bool>
</property>
<property name="flat">
<bool>false</bool>
</property>
</widget>
</widget>
<resources/>
<connections/>
</ui>
The python code doesn't show error.
Following .ui file, created with Qt 5.7 Designer, shows a text box and a spacer:
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Form</class>
<widget class="QWidget" name="Form">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>310</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QPlainTextEdit" name="plainTextEdit">
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="MinimumExpanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="plainText">
<string>abc</string>
</property>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
For example, if the text field has "abc", it should be one line high; if it has two lines (say "abc\nabc"), OR one long line that requires two lines to display, then the text box should be two lines high.
Minimum height is 0. I tried changing the sizing policy of the text box so that the widget is as small as possible, but none do this.
Equivalent Python the code to do this is:
app=QApplication([])
widget = QWidget()
widget.setLayout(QVBoxLayout())
text_widget = QPlainTextEdit('abc')
# text_widget.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.MinimumExpanding)
widget.layout().addWidget(text_widget)
spacer = QSpacerItem(20, 40, vPolicy=QSizePolicy.Expanding)
widget.layout().addSpacerItem(spacer)
widget.show()
app.exec_()
I want to create an application which consists of a QLineEdit and two QTableView widgets in vertical layout.
Sample code:
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Dialog</class>
<widget class="QDialog" name="Dialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<widget class="QWidget" name="verticalLayoutWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>401</width>
<height>301</height>
</rect>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QLineEdit" name="lineEdit"/>
</item>
<item>
<widget class="QTableView" name="tableView_2"/>
</item>
<item>
<widget class="QTableView" name="tableView"/>
</item>
</layout>
</widget>
</widget>
<resources/>
<connections>
<connection>
<sender>lineEdit</sender>
<signal>returnPressed()</signal>
<receiver>Dialog</receiver>
<slot>close()</slot>
<hints>
<hint type="sourcelabel">
<x>200</x>
<y>14</y>
</hint>
<hint type="destinationlabel">
<x>199</x>
<y>149</y>
</hint>
</hints>
</connection>
</connections>
</ui>
But these QTableView widgets are not resizable. I didn't found any property in Qt for this.
So how can I make these QTableView widgets resizable or auto expand and contract?
means if I reduce size of first QTableView widget then automatically size of second QTableView widget should increase means every widget should expand or contract automatically if I change size of any widget inside Vertical Layout at run time.
The sample code was designed in Qt4 Designer on Ubuntu 14.04.
Break the current layout, select the two widgets, click Layout Vertically in Splitter and finally select the form and click the layout vertically.
This is because you don't have a layout on your QDialog. What you did was you dragged a vertical layout on top of the dialog, now the dialog contains the layout which is absolute positioned and is not linked to the dialog. What you want to do is move the all the widgets from the vertical layout on top of a QSplitter, right click on the QDialog and at the Lay out context menu entry choose Lay Out Vertically, or alternatively click the QDialog and press Ctrl + 2. The result should be the following:
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Dialog</class>
<widget class="QDialog" name="Dialog">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>405</width>
<height>305</height>
</rect>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QSplitter" name="splitter">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<widget class="QLineEdit" name="lineEdit"/>
<widget class="QTableView" name="tableView_2"/>
<widget class="QTableView" name="tableView"/>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
What I recommend is reading the Qt Layout Management Documentation for more info on this topic.
I'm loading the .ui file, where one of the widgets (QComboBox) has a dynamic property (http://qt-project.org/doc/qt-5/properties.html#dynamic-properties). The UI file looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>PopulateScriptConfig</class>
<widget class="QWidget" name="PopulateScriptConfig">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QGroupBox" name="langGroup">
<property name="title">
<string>Language</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
<widget class="QComboBox" name="langCombo">
<property name="ScriptingLangCombo" stdset="0">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="codeGroup">
<property name="title">
<string>Implementation</string>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QPlainTextEdit" name="codeEdit"/>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
The important part is:
<widget class="QComboBox" name="langCombo">
<property name="ScriptingLangCombo" stdset="0">
<bool>true</bool>
</property>
</widget>
I'm loading the file with QUiLoader::load(). I have extended the QUiLoader class, but only to access createWidget() method, where I can query each widget like this:
QWidget* UiLoader::createWidget(const QString& className, QWidget* parent, const QString& name)
{
QWidget* w = QUiLoader::createWidget(className, parent, name);
qDebug() << w->dynamicPropertyNames();
return w;
}
As a result I see empty list displayed, so it seems like the dynamic property is completly ignored.
Note, that UI editor in QtCreator recognizes this dynamic property correclty.
This question was already asked/reported 2 times before, but no solution was provided:
https://bugreports.qt-project.org/browse/QTBUG-11791?page=com.atlassian.streams.streams-jira-plugin:activity-stream-issue-tab
http://www.qtcentre.org/threads/32013-QUiLoader-Problem-No-Dynamic-Properties-Support
Any ideas?
P.S. I've made sure that I load correct file. 3 times.
It turned out it was my mistake and Qt is working correctly. Rookie mistake.
The problem is that I tried to access dynamic properties in overriden method of QUiLoader::createWidget(), but this is invoked for each subwidget and dynamic properties are set after all widgets were created. Dynamic properties are not yet available at the moment of createWidget() call.
The very simple project I did for testing this (I mentioned it in the comment) was also working correctly, I just made a mistake while printing debug information (I was printing it from wrong widget). That's all.
QUiLoader works just fine with dynamic properties after all.
I have a simple form: QDockWidget on the right side, QGroupBox on the left side of QMainWindow. QGroupBox is layed out using vertical layout.
I want QDockWidget to be expanded and occupy all the free space when the main window is enlarged or maximized.
How do I do it?
Bellow is the source code of my .ui file.
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>653</width>
<height>381</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralwidget">
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QGroupBox" name="groupBox">
<property name="title">
<string>GroupBox</string>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QDockWidget" name="dockWidget">
<attribute name="dockWidgetArea">
<number>2</number>
</attribute>
<widget class="QWidget" name="dockWidgetContents"/>
</widget>
</widget>
<resources/>
<connections/>
</ui>
You will need to reimplement QWidget::changeEvent (or a resizeEvent for resizing) to react to QEvent::WindowStateChange. If one of those events occurs, get the QWidget::windowState and resize your dock to whatever you want.