I have this window with a few TextFields and a TableView. I have made a search engine which every time I write in the TextFields, will display a new array of the given objects which fit what ever I write in the TextFields. Now, I have tested it, and I know that the search engine works. But the problem comes when I try to update the TableView. I have tried to work my way through it, but the only fix I can think of, is to refresh the whole window every time I type something in one of the TextFields. But this is obviously not a good thing to do.
So my question is: Do you know how to refresh the list in the TableView, without refreshing the whole window? Or is there anything else I can use to visually display for example "Person" objects, make them click-able and holds pointers to the given objects?
Please come with any input you have, and I will be happy to either try or discuss what you have to say!
Found the issue!
setItems(); seems to call the object.equals();
I made a misstake in my #Override of the .equals();
#Override
public boolean equals(Object obj) {
return this.birthNo.equals(((Person) obj).getBirthNo());
}
Corrected this to:
#Override
public boolean equals(Object obj) {
return obj != null && this.birthNo.equals(((Person) obj).getBirthNo());
}
Related
In AX7, I have a FormStringControl and I want to clear the text-contents while the user has focus on it. I overrode the textChange() method, and in AX2012, this would work, but it does not in AX7:
public void textChange()
{
this.text("");
super();
}
What I expect to happen is, while the user keys-in text, it'll clear. This is a proof-of-concept thing I'm trying to accomplish for a bigger task.
EDIT: The actual task is I have a setTimeoutEx() (formerly setTimeout()) that polls a string control every 100ms and attempts to clear it sometimes. It does not work when the focus is on the string control.
I would assume that textChange is a depricated API, though this is not explicitly stated in that list. The dateTextChange method is for sure.
The reason for deprecation is obvious, it would introduce a server round-trip for each entered key, which does not scale.
I guess you will need to accomplish your task using other methods.
I am creating a small program that takes user input into a model and then shows that input in several views that take it through filters.
When the user clicks the button that accepts the input, the program updates the amount of cells in the views and then resizes those cells as necessary so that they fit neatly in their area.
My problem is that the cell resizing doesn't seem to work for one of the views for some reason (I tried looking for differences but couldn't find a reason for what I'm experiencing).
I'm calling the cell resizing function in two places:
dataChanged slot.
resizeEvent slot.
If the cell resize function gets called twice inside dataChanged, then the view does update, however this involves some calculations and ui access and obviously not supposed to happen.
If I resize my window then the cells are resized properly.
I suspect that I'm always one update behind - that the view doesn't paint until the new update starts getting calculated and then that new update is on hold until the next calculation (since resize happens a lot of times in succession it might just act the same as the button but is harder/impossible to notice).
I have some dirty workarounds:
As I mentioned, if I call my cell resize function again, the view updates properly.
If I remove the second "if" in this next piece of code then everything works.
I thought I'd save my computer some work by only processing when the entire input had been received. My thinking was that, although dataChanged is emitted for every single item I'm inserting, I only really need to update once it is all in:
void MainWindow::on_dataChanged()
{
static int left_to_insert = -1;
if ( 0 > left_to_insert )
{
left_to_insert = m_model.rowCount() - 1;
}
if ( 0 == left_to_insert )
{
...
m_matrix_proxy.resize_to_fit();
adjust_matrix_cells_sizes();
}
--left_to_insert
}
Is it bad to only process the last signal? Why?
I tried calling update() and/or repaint() on both the matrix and the main window.
I tried calling both of these on the viewport of the QTableView and tried calling them in succession from the matrix itself to the highest parent that didn't make my program crash. (ui->matrix->parentWidget()->parentWidget()...)
I tried qApp->processEvents().
I even resorted to emitting a resizeEvent, but this is overkill IMO as it makes some calculations be performed again.
Just in case it is somehow relevant: The data appears correctly. The only thing that's wrong is that the cells don't resize.
You need to emit layoutChanged signal from your model. But be care with large amounts of items, because handling of this signal may take a lot of time.
Similar questions: one, two
This logic in only code sample you have given is wrong. And this static keyword makes it even worse.
Actual answer:
There is ready solution delivered by Qt! See documentation of QHeaderView::ResizeMode and QHeaderView::setSectionResizeMode
Old answer:
IMO this should look like this:
void MainWindow::MainWindow()
…
{
…
mNeetToResizeCells = false;
connect(this, &MainWindow::NeedUpdateCellsSizes,
this, &MainWindow::ResizeTableCells,
Qt::QueuedConnection); // this is imporatant
}
void MainWindow::on_dataChanged()
{
if (!mNeetToResizeCells) {
mNeetToResizeCells = true;
emit NeedUpdateCellsSizes();
}
}
void MainWindow::ResizeTableCells()
{
mNeetToResizeCells = false;
// update cells sizes here
ui->tableView->resizeColumnsToContents();
ui->tableView->resizeRowsToContents();
}
This way all data updates performed in one iteration of event loop will cause only one invocation of MainWindow::ResizeTableCells in some future iteration of event loop.
We created a small painting application in JavaFX. A new requirement arose, where we have to warn the user, that he made changes, which are not yet persisted and asking him, if the user might like to save first before closing.
Sample Snapshot:
Unfortunately there are a lot of different Nodes, and Nodes can be changed in many ways, like for example a Polygon point can move. The Node itself can be dragged. They can be rotated and many more. So before firing a zillion events for every possible change of a Node object to the canvas I`d like to ask, if anyone might have an idea on how to simplify this approach. I am curious, if there are any listeners, that I can listen to any changes of the canvas object within the scene graph of JavaFX.
Especially since I just want to know if anything has changed and not really need to know the specific change.
Moreover, I also do not want to get every single event, like a simple select, which causes a border to be shown around the selected node (like shown on the image), which does not necessary mean, that the user has to save his application before leaving.
Anyone have an idea? Or do I really need to fire Events for every single change within a Node?
I think you are approaching this problem in the wrong way. The nodes displayed on screen should just be a visual representation of an underlying model. All you really need to know is that the underlying model has changed.
If, for example, you were writing a text editor, the text displayed on the screen would be backed by some sort of model. Let's assume the model is a String. You wouldn't need to check if any of the text nodes displayed on screen had changed you would just need to compare the original string data with the current string data to determine if you need to prompt the user to save.
Benjamin's answer is probably the best one here: you should use an underlying model, and that model can easily check if relevant state has changed. At some point in the development of your application, you will come to the point where you realize this is the correct way to do things. It seems like you have reached that point.
However, if you want to delay the inevitable redesign of your application a little further (and make it a bit more painful when you do get to that point ;) ), here's another approach you might consider.
Obviously, you have some kind of Pane that is holding the objects that are being painted. The user must be creating those objects and you're adding them to the pane at some point. Just create a method that handles that addition, and registers an invalidation listener with the properties of interest when you do. The structure will look something like this:
private final ReadOnlyBooleanWrapper unsavedChanges =
new ReadOnlyBooleanWrapper(this, "unsavedChanged", false);
private final ChangeListener<Object> unsavedChangeListener =
(obs, oldValue, newValue) -> unsavedChanges.set(true);
private Pane drawingPane ;
// ...
Button saveButton = new Button("Save");
saveButton.disableProperty().bind(unsavedChanges.not());
// ...
#SafeVarArgs
private final <T extends Node> void addNodeToDrawingPane(
T node, Function<T, ObservableValue<?>>... properties) {
Stream.of(properties).forEach(
property -> property.apply(node).addListener(unsavedChangeListener));
drawingPane.getChildren().add(node);
}
Now you can do things like
Rectangle rect = new Rectangle();
addNodeToDrawingPane(rect,
Rectangle::xProperty, Rectangle::yProperty,
Rectangle::widthProperty, Rectangle::heightProperty);
and
Text text = new Text();
addNodeToDrawingPane(text,
Text::xProperty, Text::yProperty, Text::textProperty);
I.e. you just specify the properties to observe when you add the new node. You can create a remove method which removes the listener too. The amount of extra code on top of what you already have is pretty minimal, as (probably, I haven't seen your code) is the refactoring.
Again, you should really have a separate view model, etc. I wanted to post this to show that #kleopatra's first comment on the question ("Listen for invalidation of relevant state") doesn't necessarily involve a lot of work if you approach it in the right way. At first, I thought this approach was incompatible with #Tomas Mikula's mention of undo/redo functionality, but you may even be able to use this approach as a basis for that too.
I use a custom class (Configuration) derived from QGraphicsItem and I add its objects to a QGraphicsScene, which is then displayed in a QGraphicsView. Usual stuff. What Im doing exactly is drawing a tree, in multiple steps, one level a step, each node beeing my custom QGraphicsItem.
Here a screenshot. The tree happens to be sequential in the simple case.
I first draw the root node. The signal that triggers that is fired after the user entered a string.
void MainWindow::drawRootSlot(ConfigTreeBuilder & builder)//this is a slot
{
c_scene->clear(); //the clear cause headache. i'll expain
Configuration* conf = new Configuration(builder.getNodesX(), builder.getNodesY(),builder.getNodesConfig());
//code
c_scene->addItem(conf);
//code
}
Each subsequent Configuration is draw inside another slot.
void MainWindow::configTreeSlot(ConfigTreeBuilder & builder) //SLOT!!!
{
while(builder.chooseNextNode()) {
Configuration* conf = new Configuration(builder.getNodesX(), builder.getNodesY(), builder.getNodesConfig());
//code, while loop
QGraphicsLineItem *edge = c_scene->addLine(QLineF(*(parentsPoint), conf->getLeftOrigin()));
edge->setZValue(-1); //below the Configuration item
c_scene->addItem(conf);
}
}
All works fine when done for the first time. When I enter a new string, resetting the tree, dark magic happens. What I expected to it do is: call drawRootSlot(), deleting the whole tree (c_scene->clear()), draw a new root node. And, if I put a debugger breakpoint inside drawRootSlot() this is exactly what happens! But when I run it (without breakpoints), what I get is this:
The previous tree got mangled, but not deleted. The scene gets indeed cleared of its items (printed that) but the view does not reflect that. But again, when I put a breakpoint inside drawRootSlot() thhe view and the scene are in sync.
I tried to delete the scene object, and instaciate a new one instead of calling c_scene->clear(), to guarantee it empty. Then the changes are reflected on the view (the first time drawing always works).
So, I have no idea what to deduce from these symptoms. It works as expected with a breakpoint or with a freshh QGraphicsScene object. It does not when just using c_scene->clear(). One couldsay I just messed up the parent-object/child-object relation, but clear() does remove items from the view... I tried calling it right after c_scene->addItem().
What is this sorrcery? One that makes me believe I'm not actually stupid?
EDIT: Whats interesting and may be a hint to the real problem, is that when c_scene->clear() is called, the edges of the tree, which are normal QGraphicsLineItems, are indeed deleted in all cases (breakpoint or not). Something to do with them not beeing custom?
Ok, calling QGraphicsView::viewport().update() after QGraphicsScene::clear() solved my problems.
But does anyone have an explanaition to the behavior described above?
EDIT: Upon doing doing something else I stumbled upon the actual core of the problem: I messed up the boundingRect() of my GraphicItems, so it was below the visble item, touching only its lower edge (which got deleted, as seen on the screenshot). So now no calls to any update() methods are neccesary.
I think when you call this fitInView() for the graphicsview it cleans up the view from any artifacts that remain from a previous scene.
You can clear both scene and Graphics View
scene->clear();
ui->graphicsView->items().clear();
graphicsView = name of your graphics view
This code will delete both scene and graphics view
I am trying to learn delegates in C# from this article
http://msdn.microsoft.com/en-us/library/aa288459(v=vs.71).aspx
I am able to understand the code a bit but i am not able to understand where and why would a developer want to use delegates. Can somebody give an easy scenario which can help me start with delegates?
Update
I read this statement everywhere, "The delegate object can then be passed to code which can call the referenced method, without having to know at compile time which method will be invoked."
But why would i want compiler shouldn't know about function i pass? I can smell abstraction here but what's the use? Any real time scenario is required.
A good example of using delegates would be callbacks. Imagine you have a class DbSearcher. That class has the method Search(string q) and when you call this method it takes it 1 minute to return. You want to eventually display results of the search but you don't want to keep the user waiting for them to appear while being unable to do anything more. What you do is you change your method to, for example, Search(string q, Action displayResults) and fire it in a separate thread. displayResults here is a delegate which you will call inside the Search method once the search results are retrieved from the db.
Look, in windows forms there are classes like button, image, textbox etc... All of them have event handlers like button.click, textbox.texchange, ... which are delegates themselves.
and when you want to do something on button click you write function which is void and has two aguments: of object type and EventArgs. The one who wrote that button class didnot know what to do on button click but gave you delegate:
public delegate EventHandler Click;
where will be your defined methods like:
public void mymethod(object s, EventArgs e)
or every method tha is void and has that parameters
You can find so many example and code snippets over the web . Here is my example, think that your user is going to decide which operation he/she is going to do in the following,
Add two numbers
Subtract two numbers
Multiple two numbers
Divide two numbers.
But you have one common method to perform all this
Operation(some delgate method)
{
// do some operation
}
u you can pass the delegate at run time based on user selection.
This is just an example.
A delegate is basically a reference to a method.
You can for example have to different methods for changing a string:
public static string ChangeOne(string s) {
return s.TrimStart();
}
public static string ChangeTwo(string s) {
return s.TrimEnd();
}
Depending on some criteria, you can choose between them, and put the choice in a delegate:
Func<string, string> change;
if (DateTime.Today.DayOfWeek == DayOfWeek.Sunday) {
change = ChangeOne;
} else {
change = ChangeTwo;
}
Then you can use the delegate just a regular method. The code that uses it doesn't have to know what the method does, or why:
string x = " asdf ";
x = change(x);
Delegates are for example widely used for generic collections, where the library methods doesn't have to know anything about the objects in the collection. You just provide it with a delegate to a method that picks out the relevant information.
Here the Where method doesn't know anything about the objects in the list, it only gets a delegate to a method that determines if an object should be included in the result or not:
IEnumerable<obj> older = listOfObj.Where(o => o.Age >= 18);