Qt: resize MainWindow and its contents according to the resolution of monitor - visual-studio-2010

I want to display MainWindow, in full screen and its contents should resize accordingly to the size of the monitor:
My MainWindow.ui:
<?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>820</width>
<height>651</height>
</rect>
</property>
<property name="windowTitle">
<string>metaio SDK – Qt Tutorials</string>
</property>
<widget class="QWidget" name="centralwidget">
<property name="layoutDirection">
<enum>Qt::LeftToRight</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_4">
<item>
<layout class="QVBoxLayout" name="mainLayout">
<item alignment="Qt::AlignHCenter">
<widget class="QGraphicsView" name="graphicsView">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>1300</width>
<height>768</height>
</size>
</property>
<property name="resizeAnchor">
<enum>QGraphicsView::NoAnchor</enum>
</property>
</widget>
</item>
<item>
<layout class="QHBoxLayout" name="buttonLayout">
<item>
<widget class="QPushButton" name="quitTutorialButton">
<property name="font">
<font>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>« Back</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</widget>
</widget>
<resources/>
<connections/>
<slots>
<slot>on_load_arel()</slot>
<slot>on_load_file()</slot>
<slot>on_close_tab(int)</slot>
<slot>on_save_and_preview()</slot>
<slot>on_preview_channel()</slot>
</slots>
</ui>
some code of my MainWindow.cpp:
...
setupUi(this);
quitTutorialButton->setVisible(false);
QObject::connect(quitTutorialButton, SIGNAL(clicked()), this, SLOT(onQuitTutorialButtonClicked()));
m_pMenu = new Menu(this, this);
// Init the main view for the scene using OpenGL
QGLWidget *glWidget = new QGLWidget(QGLFormat(QGL::SampleBuffers));
m_pGraphicsView = graphicsView;
m_pGraphicsView->setScene(m_pMenu);
m_pGraphicsView->setViewport(glWidget);
m_pGraphicsView->setFrameShape(QFrame::NoFrame);
some code in my Menu.cpp:
m_pWebView = new QGraphicsWebView();
addItem(m_pWebView);
m_pWebView->resize(1300, 768); // dont want this to be static
QObject::connect(m_pWebView, SIGNAL(linkClicked(const QUrl&)), this, SLOT(linkClicked(const QUrl&)));
QTimer::singleShot(20, this, SLOT(loadContent()));
Please help me out.
Edit:
If you see, i have added QGraphicsWebView programatically. I am running this solution on my notebook, with 1366 x 768 resolution. If i want to use entire screen space, i have to give size to my QGraphicsWebView (line with comment added at the end) and to my QGraphicsView that lies in my MainWindow.ui. I want to remove this static part, and make it dynamic.

If you're using QLayout managers then all you should need to do is set the window state to full screen: QWidget::setWindowState. The layout managers should take care of the rest, most likely you'll need to set the spacing and use some QSpacers to get the elements exactly where you want them.

About the fullscreen issue: have you tried with QMainWindow::showFullScreen() ?
Reply to the edit:
I don't see any reason for those nested layouts, it is kinda messed up. Instead of having
-- mainLayout
|-- graphicsView
|-- buttonLayout <- why layout only one element??
|-- quitTutorialButton
try with this simpler layout
-- mainLayout
|-- graphicsView
|-- quitTutorialButton
Then, change the fixed size policy to MinimumExpanding instead.
Last advice: since looks like you layout your items by hand, never insert the outermost layout by hand. If you do so, the elements in it will never scale to the QMainWindow size.
Instead, right-click in an empty portion of the central widget, select Layout and then choose the type of layout you want to apply. This of course is needed only for the outmost layout: for the remaining, inner ones, you can add them by simple drag&drop as usual.

Related

get_activate not found in gtk::Swtich

I've been following a project based book which uses gtk and glade to build a UI. Went all fine until I got to using a gtk::Switch which the book uses like this:
let builder = gtk::Builder::from_string(include_str!("glade_config.glade"));
// ...
let is_dead_switch: gtk::Switch = builder
.get_object("is_dead_switch")
.unwrap();
Later on, to get the switch state it uses is_dead_switch.get_activate() but the method seems to no longer be a thing. I've looked into the documentation and found that gtk::Switch only has gtk::Switch::new listed as method. Anyone knows what's missing or what's wrong?
Cargo.toml dependencies:
[dependencies]
gio = "0.9.1"
[dependencies.gtk]
version = "0.9.2"
features = ["v3_22"]
glade config file stating this part:
<child>
<object class="GtkSwitch" id="is_dead_switch">
<property name="visible">True</property>
<property name="can_focus">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">True</property>
<property name="position">1</property>
</packing>
</child>

Why starting a non-responsive service from a QThread blocks the main GUI?

PyQt 5
Python 3.5
I have a Windows service that cannot be started for a few seconds after it has been stopped. If you try it returns error 1053. When I try to start it during this "unresponsiveness period" with win32serviceutil. StartService() from a QThread (with a worker inside), StartService() runs for about 20 seconds and finally returns error 1053. The problem is that despite StartService() being run in a separate thread, it will also block the main GUI thread. Here's my sample code:
import sys
from PyQt5 import uic
from PyQt5.QtWidgets import QApplication, QMainWindow, QMessageBox
from PyQt5.QtCore import Qt, QObject, QThread, pyqtSignal, pyqtSlot
from win32serviceutil import StartService
class Worker(QObject):
finished = pyqtSignal()
done = pyqtSignal("PyQt_PyObject")
def __init__(self, func, *args):
super().__init__()
self.func = func
self.args = args
def run(self):
try:
result = self.func(*self.args)
except Exception as e:
result = e
self.done.emit(result) # Pass function return.
self.finished.emit()
Ui_MainWindow, QtBaseClass = uic.loadUiType("window.ui")
class TestApp(QMainWindow, Ui_MainWindow):
def __init__(self):
super().__init__()
self.setupUi(self)
# Hide What's This button and show only close button.
self.setWindowFlags(Qt.WindowTitleHint | Qt.WindowCloseButtonHint)
self.text_box.returnPressed.connect(self.run_thread)
self.worker = None
self.thread = None
self.go_button.clicked.connect(self.run_thread)
def run_thread(self):
if self.text_box.text().strip():
# Start service from generic worker inside a QThread.
self.worker = Worker(StartService, self.text_box.text().strip())
self.thread = QThread()
self.worker.moveToThread(self.thread)
self.thread.started.connect(self.worker.run)
self.worker.done.connect(self.done)
self.worker.finished.connect(self.thread.quit)
self.worker.finished.connect(self.worker.deleteLater)
self.thread.finished.connect(self.thread.deleteLater)
self.thread.start()
self.busy(True) # Activate progress busy mode.
def busy(self, status):
end = 0 if status else 100 # 0 is busy progress bar, 100 is inactive.
self.p_bar.setRange(0, end)
#pyqtSlot("PyQt_PyObject")
def done(self, result):
self.busy(False) # Deactivate progress bar.
if isinstance(result, Exception):
title = "Error"
msg = str(result)
icon = QMessageBox.Critical
else:
title = "Started"
msg = "Done"
icon = QMessageBox.Information
# Show message box with result.
dialog = QMessageBox(self)
dialog.setWindowTitle(title)
dialog.setText(msg)
dialog.setStandardButtons(QMessageBox.Ok)
dialog.setIcon(icon)
dialog.exec_()
def main():
program = QApplication(sys.argv)
svc_stopper = TestApp()
svc_stopper.show()
sys.exit(program.exec_())
if __name__ == "__main__":
main()
This is the window.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>230</width>
<height>120</height>
</rect>
</property>
<property name="windowTitle">
<string>Start Service</string>
</property>
<widget class="QWidget" name="centralwidget">
<widget class="QPushButton" name="go_button">
<property name="geometry">
<rect>
<x>76</x>
<y>13</y>
<width>81</width>
<height>31</height>
</rect>
</property>
<property name="text">
<string>Start Service</string>
</property>
<property name="autoDefault">
<bool>true</bool>
</property>
</widget>
<widget class="QProgressBar" name="p_bar">
<property name="geometry">
<rect>
<x>10</x>
<y>90</y>
<width>211</width>
<height>23</height>
</rect>
</property>
<property name="value">
<number>0</number>
</property>
<property name="textVisible">
<bool>false</bool>
</property>
</widget>
<widget class="QLineEdit" name="text_box">
<property name="geometry">
<rect>
<x>10</x>
<y>60</y>
<width>211</width>
<height>20</height>
</rect>
</property>
<property name="placeholderText">
<string>Service display name</string>
</property>
<property name="clearButtonEnabled">
<bool>false</bool>
</property>
</widget>
</widget>
</widget>
<tabstops>
<tabstop>go_button</tabstop>
</tabstops>
<resources/>
<connections/>
</ui>

How can I get a pathname from a groupId? [duplicate]

Is there a simple way of taking the value of a property and then copy it to another property with certain characters replaced?
Say propA=This is a value. I want to replace all the spaces in it into underscores, resulting in propB=This_is_a_value.
Here is the solution without scripting and no external jars like ant-conrib:
The trick is to use ANT's resources:
There is one resource type called "propertyresource" which is like a source file, but provides an stream from the string value of this resource. So you can load it and use it in any task like "copy" that accepts files
There is also the task "loadresource" that can load any resource to a property (e.g., a file), but this one could also load our propertyresource. This task allows for filtering the input by applying some token transformations. Finally the following will do what you want:
<loadresource property="propB">
<propertyresource name="propA"/>
<filterchain>
<tokenfilter>
<filetokenizer/>
<replacestring from=" " to="_"/>
</tokenfilter>
</filterchain>
</loadresource>
This one will replace all " " in propA by "_" and place the result in propB. "filetokenizer" treats the whole input stream (our property) as one token and appies the string replacement on it.
You can do other fancy transformations using other tokenfilters: http://ant.apache.org/manual/Types/filterchain.html
Use the propertyregex task from Ant Contrib.
I think you want:
<propertyregex property="propB"
input="${propA}"
regexp=" "
replace="_"
global="true" />
Unfortunately the examples given aren't terribly clear, but it's worth trying that. You should also check what happens if there aren't any underscores - you may need to use the defaultValue option as well.
If ant-contrib isn't an option, here's a portable solution for Java 1.6 and later:
<property name="before" value="This is a value"/>
<script language="javascript">
var before = project.getProperty("before");
project.setProperty("after", before.replaceAll(" ", "_"));
</script>
<echo>after=${after}</echo>
In case you want a solution that does use Ant built-ins only, consider this:
<target name="replace-spaces">
<property name="propA" value="This is a value" />
<echo message="${propA}" file="some.tmp.file" />
<loadfile property="propB" srcFile="some.tmp.file">
<filterchain>
<tokenfilter>
<replaceregex pattern=" " replace="_" flags="g"/>
</tokenfilter>
</filterchain>
</loadfile>
<echo message="$${propB} = "${propB}"" />
</target>
Output is ${propB} = "This_is_a_value"
Use some external app like sed:
<exec executable="sed" inputstring="${wersja}" outputproperty="wersjaDot">
<arg value="s/_/./g"/>
</exec>
<echo>${wersjaDot}</echo>
If you run Windows get it googling for "gnuwin32 sed".
The command s/_/./g replaces every _ with .
This script goes well under windows. Under linux arg may need quoting.
Two possibilities :
via script task and builtin javascript engine (if using jdk >= 1.6)
<project>
<property name="propA" value="This is a value"/>
<script language="javascript">
project.setProperty('propB', project.getProperty('propA').
replace(" ", "_"));
</script>
<echo>$${propB} => ${propB}</echo>
</project>
or using Ant addon Flaka
<project xmlns:fl="antlib:it.haefelinger.flaka">
<property name="propA" value="This is a value"/>
<fl:let> propB := replace('${propA}', '_', ' ')</fl:let>
<echo>$${propB} => ${propB}</echo>
</project>
to overwrite exisiting property propA simply replace propB with propA
Here's a more generalized version of Uwe Schindler's answer:
You can use a macrodef to create a custom task.
<macrodef name="replaceproperty" taskname="#{taskname}">
<attribute name="src" />
<attribute name="dest" default="" />
<attribute name="replace" default="" />
<attribute name="with" default="" />
<sequential>
<loadresource property="#{dest}">
<propertyresource name="#{src}" />
<filterchain>
<tokenfilter>
<filetokenizer/>
<replacestring from="#{replace}" to="#{with}"/>
</tokenfilter>
</filterchain>
</loadresource>
</sequential>
</macrodef>
you can use this as follows:
<replaceproperty src="property1" dest="property2" replace=" " with="_"/>
this will be pretty useful if you are doing this multiple times
Adding an answer more complete example over a previous answer
<property name="propB_" value="${propA}"/>
<loadresource property="propB">
<propertyresource name="propB_" />
<filterchain>
<tokenfilter>
<replaceregex pattern="\." replace="/" flags="g"/>
</tokenfilter>
</filterchain>
</loadresource>
Just an FYI for answer Replacing characters in Ant property - if you are trying to use this inside of a maven execution, you can't reference maven variables directly. You will need something like this:
...
<target>
<property name="propATemp" value="${propA}"/>
<loadresource property="propB">
<propertyresource name="propATemp" />
...
Properties can't be changed but antContrib vars (http://ant-contrib.sourceforge.net/tasks/tasks/variable_task.html ) can.
Here is a macro to do a find/replace on a var:
<macrodef name="replaceVarText">
<attribute name="varName" />
<attribute name="from" />
<attribute name="to" />
<sequential>
<local name="replacedText"/>
<local name="textToReplace"/>
<local name="fromProp"/>
<local name="toProp"/>
<property name="textToReplace" value = "${#{varName}}"/>
<property name="fromProp" value = "#{from}"/>
<property name="toProp" value = "#{to}"/>
<script language="javascript">
project.setProperty("replacedText",project.getProperty("textToReplace").split(project.getProperty("fromProp")).join(project.getProperty("toProp")));
</script>
<ac:var name="#{varName}" value = "${replacedText}"/>
</sequential>
</macrodef>
Then call the macro like:
<ac:var name="updatedText" value="${oldText}"/>
<current:replaceVarText varName="updatedText" from="." to="_" />
<echo message="Updated Text will be ${updatedText}"/>
Code above uses javascript split then join, which is faster than regex. "local" properties are passed to JavaScript so no property leakage.
Or... You can also to try Your Own Task
JAVA CODE:
class CustomString extends Task{
private String type, string, before, after, returnValue;
public void execute() {
if (getType().equals("replace")) {
replace(getString(), getBefore(), getAfter());
}
}
private void replace(String str, String a, String b){
String results = str.replace(a, b);
Project project = getProject();
project.setProperty(getReturnValue(), results);
}
..all getter and setter..
ANT SCRIPT
...
<project name="ant-test" default="build">
<target name="build" depends="compile, run"/>
<target name="clean">
<delete dir="build" />
</target>
<target name="compile" depends="clean">
<mkdir dir="build/classes"/>
<javac srcdir="src" destdir="build/classes" includeantruntime="true"/>
</target>
<target name="declare" depends="compile">
<taskdef name="string" classname="CustomString" classpath="build/classes" />
</target>
<!-- Replacing characters in Ant property -->
<target name="run" depends="declare">
<property name="propA" value="This is a value"/>
<echo message="propA=${propA}" />
<string type="replace" string="${propA}" before=" " after="_" returnvalue="propB"/>
<echo message="propB=${propB}" />
</target>
CONSOLE:
run:
[echo] propA=This is a value
[echo] propB=This_is_a_value

Why are Gdk::Pixbufs not visible in Gtk::TreeView?

After spending a long time searching for an answer, I hope someone can help me with this problem. I'm trying to use gtkmm (version 3.14.0) and glade (version 3.18.3) on a Fedora 21 system to create a Gtk::TreeView/Gtk::ListStore with many small images. I can easily place stock icons in the list, but adding Gdk::Pixbuf objects seems to go wrong. No error or warning messages are shown, but the Gdk::Pixbuf image is not shown.
To show the problem, I've created a minimal working example (the code of the program and the glade file included at the end). Running this program should open a small window with the Gtk::TreeView with two "gtk-apply" icons. In the first column should be the icon added as Gdk::Pixbuf, in the second column should be the stock icon. However, when I run the program, the first column remains empty. There are no compile or run-time errors or warnings.
My final application will display a matrix of about 100 rows and about 35 columns of mostly tiny icons allowing a quick overview of activities done on the different days of a month. None of these icons will be stock icons.
Extra Information: Following the program execution using a debugger, I found that the Gtk::ListStore's first column wants data of type gtkmm__GdkPixbuf. The type of pb in the line row[cols.m_pb] = pb is GdkPixbuf. The type GdkPixbuf cannot be converted to gtkmm__GdkPixbuf automatically, causing the value to be set to 0 (NULL). Obviously this does not solve the problem, but might help to solve the problem.
Thanks for the help and best wishes for 2015,
Wim
This is the file mwe.glade:
<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.18.3 -->
<interface>
<requires lib="gtk+" version="3.12"/>
<object class="GtkAccelGroup" id="accelgroup1"/>
<object class="GtkApplicationWindow" id="mainwindow">
<property name="can_focus">False</property>
<property name="show_menubar">False</property>
<child>
<object class="GtkGrid" id="mainbox">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="orientation">vertical</property>
<child>
<object class="GtkTreeView" id="treattree">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="vexpand">True</property>
<property name="hscroll_policy">natural</property>
<property name="model">treatstore</property>
<property name="rules_hint">True</property>
<property name="search_column">0</property>
<property name="fixed_height_mode">True</property>
<child internal-child="selection">
<object class="GtkTreeSelection" id="sel1"/>
</child>
<child>
<object class="GtkTreeViewColumn" id="col1">
<property name="sizing">fixed</property>
<property name="fixed_width">32</property>
<property name="title">1</property>
<child>
<object class="GtkCellRendererPixbuf" id="cell1">
<property name="width">16</property>
<property name="height">16</property>
</object>
<attributes>
<attribute name="pixbuf">0</attribute>
</attributes>
</child>
</object>
</child>
<child>
<object class="GtkTreeViewColumn" id="col2">
<property name="sizing">fixed</property>
<property name="fixed_width">32</property>
<property name="title">2</property>
<child>
<object class="GtkCellRendererPixbuf" id="cell2"/>
<attributes>
<attribute name="stock-id">1</attribute>
</attributes>
</child>
</object>
</child>
</object>
<packing>
<property name="left_attach">0</property>
<property name="top_attach">0</property>
</packing>
</child>
</object>
</child>
</object>
<object class="GtkListStore" id="treatstore">
<columns>
<!-- column-name col1 -->
<column type="GdkPixbuf"/>
<!-- column-name col2 -->
<column type="gchararray"/>
</columns>
</object>
</interface>
The file mwe.cpp:
#include <gtkmm.h>
namespace ws
{
class App : public Gtk::Application
{
protected:
App() : Gtk::Application("nl.mwe.mwe"), m_mainwindow(0)
{
Glib::set_application_name("MWE");
}
public:
static Glib::RefPtr<App> create(int &argc, char **&argv)
{
return Glib::RefPtr<App>(new App());
}
void init(Glib::RefPtr<Gtk::Builder> builder);
int run()
{
return Gtk::Application::run(*m_mainwindow);
}
private:
Gtk::ApplicationWindow *m_mainwindow;
};
// Definition of the column references
class ModelColumns : public Gtk::TreeModelColumnRecord
{
public:
ModelColumns()
{
add(m_pb);
add(m_stock);
}
Gtk::TreeModelColumn<Glib::RefPtr<Gdk::Pixbuf> > m_pb;
Gtk::TreeModelColumn<Glib::ustring> m_stock;
};
static ModelColumns col;
} // End namespace ws
/**
* \brief Initialize the app
* \param[in] builder The builder object
*
* Here is where the list store is populated with the Gdk::Pixbuf
*/
void ws::App::init(Glib::RefPtr<Gtk::Builder> builder)
{
builder->get_widget("mainwindow", m_mainwindow);
m_mainwindow->show();
Glib::RefPtr<Gtk::ListStore> store =
Glib::RefPtr<Gtk::ListStore>::cast_static(
builder->get_object("treatstore"));
Gtk::TreeModel::Row row = *store->append();
// The line below loads the stock icon as a pixbuf.
Glib::RefPtr<Gdk::Pixbuf> pb =
Gtk::IconTheme::get_default()->load_icon("gtk-apply", 16);
row[col.m_pb] = pb;
row[col.m_stock] = "gtk-apply";
}
int main (int argc, char *argv[])
{
Glib::RefPtr<ws::App> myapp = ws::App::create(argc, argv);
Glib::RefPtr<Gtk::Builder> builder = Gtk::Builder::create();
builder->add_from_file("mwe.glade");
myapp->init(builder);
return myapp->run();
}
After finding the problems in the types as shown in the Extra Information
section in the question, I decided to create the store by hand. The definition
of the GtkListStore was removed from the glade file. The ws::App::init()
method was changed to:
void ws::App::init(Glib::RefPtr<Gtk::Builder> builder)
{
builder->get_widget("mainwindow", m_mainwindow);
Gtk::TreeView *treeview = 0;
builder->get_widget("treattree", treeview);
Glib::RefPtr<Gtk::ListStore> store =
Gtk::ListStore::create(col);
treeview->set_model(store);
Gtk::TreeModel::Row row = *store->append();
// The line below loads the stock icon as a pixbuf.
Glib::RefPtr<Gdk::Pixbuf> pb =
Gtk::IconTheme::get_default()->load_icon("gtk-apply", 16);
row[col.m_pb] = pb;
row[col.m_stock] = "gtk-apply";
m_mainwindow->show();
}
Although this is not as flexible as hoped, it does fix the problem.

Use of text() function when using xPath in dom4j

I have inherited an application that parses xml using dom4j and xPath:
The xml being parsed is similar to the following:
<cache>
<content>
<transaction>
<page>
<widget name="PAGE_ID">WRK_REGISTRATION</widget>
<widget name="TRANS_DETAIL_ID">77145</widget>
<widget name="GRD_ERRORS" />
</page>
<page>
<widget name="PAGE_ID">WRK_REGISTRATION</widget>
<widget name="TRANS_DETAIL_ID">77147</widget>
<widget name="GRD_ERRORS" />
</page>
<page>
<widget name="PAGE_ID">WRK_PROCESSING</widget>
<widget name="TRANS_DETAIL_ID">77152</widget>
<widget name="GRD_ERRORS" />
</page>
</transaction>
</content>
</cache>
Individual Nodes are being searched using the following:
String xPathToGridErrorNode = "//cache/content/transaction/page/widget[#name='PAGE_ID'][text()='WRK_DNA_REGISTRATION']/../widget[#name='TRANS_DETAIL_ID'][text()='77147']/../widget[#name='GRD_ERRORS_TEMP']";
org.dom4j.Element root = null;
SAXReader reader = new SAXReader();
Document document = reader.read(new BufferedInputStream(new ByteArrayInputStream(xmlToParse.getBytes())));
root = document.getRootElement();
Node gridNode = root.selectSingleNode(xPathToGridErrorNode);
where xmlToParse is a String of xml similar to the excerpt provided above.
The code is trying to obtain the GRD_ERROR node for the page with the PAGE_ID and TRANS_DETAIL_ID provided in the xPath.
I am seeing an intermittent (~1-2%) failure (returned node is null) of this selectSingleNode request even though the requested node is in the xml being searched.
I know there are some gotchas associated with using text()= in xPath and was wondering if there was a better way to format the xPath string for this type of search.
From your snippets, there is a problem regarding GRD_ERRORS vs. GRD_ERRORS_TMP and WRK_REGISTRATION vs. WRK_DNA_REGISTRATION.
Ignoring that, I would suggest to rewrite
//cache/content/transaction/page
/widget[#name='PAGE_ID'][text()='WRK_DNA_REGISTRATION']
/../widget[#name='TRANS_DETAIL_ID'][text()='77147']
/../widget[#name='GRD_ERRORS_TEMP']
as
//cache/content/transaction/page
[widget[#name='PAGE_ID'][text()='WRK_REGISTRATION']]
[widget[#name='TRANS_DETAIL_ID'][text()='77147']]
/widget[#name='GRD_ERRORS']
Just because it makes the code, in my eyes, easier to read, and expresses what you seem to mean more clearly: “the page element that has children with these conditions, and then take the widget with this #name.” Or, if that is closer to how you think about it,
//cache/content/transaction/page/widget[#name='GRD_ERRORS']
[preceding-sibling::widget[#name='PAGE_ID'][text()='WRK_REGISTRATION']]
[preceding-sibling::widget[#name='TRANS_DETAIL_ID'][text()='77147']]

Resources